首页
论坛
专栏
课程

[原创]逆向RegisterClass

2011-9-7 18:44 4048
yarpee
1

[原创]逆向RegisterClass

2011-9-7 18:44
4048
菜鸟级别的,高手就不用看了,欢迎指导。

心血来潮逆了下RegisterClass,结果RegisterClass--->RegisterClassExWOW--->NtUserRegisterClassExWOW--->System Call

本来只打算逆RegisterClass的,结果主要逻辑在RegisterClassExWOW中,逆了大部分,应该能管中窥豹了。RegisterClassExWOW中有些变量类型不是很清楚(指针、句柄或整型),我权且当int了。System Call部分没看。


ATOM WINAPI RegisterClassA(__in  const WNDCLASSA *lpWndClass)
{
	WNDCLASSEXA wcex;
	wcex.cbSize = sizeof(WNDCLASSEX);    // 30h
	memcpy(((char *)&wcex) + 4, lpWndClass, sizeof(WNDCLASS));
	wcex.hIconSm = NULL;
	return RegisterClassExWOWA(&wcex, 0, 0, 0x100);
}


RegisterClassExWOW就不上图了,直接写出我逆的结果,大家要看码的话,直接把User32.dll拖到IDA看吧。
HINSTANCE _hmodUser = 0;
ATOM WINAPI RegisterClassExWOWA(const WNDCLASSEXA *lpWndClassEx, int p2, int p3, int p4)
{
	if(0 == HIWORD(p3))
	{
		if(lpWndClassEx->cbClsExtra < 0 || lpWndClassEx->cbWndExtra < 0)
		{
			SetLastError(0x57);    // ERROR_INVALID_PARAMETER
			return 0;
		}
		if(_hmodUser == lpWndClassEx->hInstance)
		{
			if(*(int *)(NtCurrentTeb() + 0x6D4) < 0x400)
			{
				SetLastError(0x57);
				return 0;
			}
			if(NULL == lpWndClassEx->hInstance)
			{
				lpWndClassEx->hInstance = GetModuleHandleA(NULL);
			}

			int ver;
			if(NULL == lpWndClassEx->hInstance)
			{
				ver = RtlGetExpWinVer(GetModuleHandleA(NULL));
			}
			else
			{
				ver = RtlGetExpWinVer(lpWndClassEx->hInstance);
			}


			if(0x0F7FC0114 == lpWndClassEx->style)
			{
				if(ver > 0x30A)    // Windows版本与样式不符
				{
					SetLastError(0x57);
					return 0;
				}
				lpWndClassEx->style &= 0x803FEEB
			}

			if(lpWndClassEx->hbrBackground > 0x1F)    // 小于0x1F的画刷没有Windows版本的限制,都支持
			{
				if(0 == GdiValidateHandle(lpWndClassEx->hbrBackground))    // 无效的
				{
					if(ver > 0x300)
					{
						SetLastError(0x57);
						return 0;
					}
					lpWndClassEx->hbrBackground = 0;
				}
			}

			int n;
			HMEMU hMem;
			if(InitClsMemuNameA(&hMem, lpWndClassEx->lpszMenuName, &n))    // 失败
			{
				return 0;
			}

			p4 |= 2;
			WNDCLASSEXA wcex;
			memcpy(&wcex, lpWndClassEx, sizeof(WNDCLASSEXA));
			if(ver > 0x30A)
			{
				p4 |= 0x80;
			}
			if(*(char *)(NtCurrentTeb() + 0x6E0) != 2)
			{
				if(GetAppCompatFlags2(0x9900) != 0x800000)
				{
					p4 &= 0xBFFFFFFF;
				}
			}
			if(int((p4 << 8) >> 24) != 1)
			{
				int x;
				if(NULL == ClassNameToVersion(lpWndClassEx->lpszClassName, &x, 0, 1))
				{
					ver = 0;
					// 从 loc_77D1A552 开始下面的流程是根据临时指针变量是否为NULL来释放资源
					if([ebp+var_138] == 0)    // [ebp+var_138]在函数入口处确实被赋值为0
					{
						RtlFreeHeap(NULL, 0, 0);
					}
					// ...
					return ver;
				}
				else
				{
					// 调用NtUserRegisterClassExWOW
					// NtUserRegisterClassExWOW进入系统调用,调用号11E8h
				}
			}
		}
		else
		{
			// lpWndClassEx->hInstance有值
		}
	}
	else
	{

	}
}


NtUserRegisterClassExWOW部分比较简单是直接进行系统调用
mov eax, 11E8h
mov edx, 7FFE0300h
call dword ptr [edx]
retn 1Ch


有几个不清楚的地方,在此也提出来问下坛子里的大大们:
RegisterClassExWOW部分有几处用到了TEB中的变量,但其偏移在WinDbg中却没显示,可能是微软故意没公开,不知道有没有方法查看,或者直接告诉我这几处偏移的意义。
NtCurrentTeb() + 0x6D4
NtCurrentTeb() + 0x6E0

[推荐]看雪企服平台,提供安全分析、定制项目开发、APP等级保护、渗透测试等安全服务!

上传的附件:
上一主题 下一主题
最新回复 (0)
游客
登录 | 注册 方可回帖
返回