菜鸟级别的,高手就不用看了,欢迎指导。
心血来潮逆了下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); }
代码:
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 { } }
代码:
mov eax, 11E8h mov edx, 7FFE0300h call dword ptr [edx] retn 1Ch
RegisterClassExWOW部分有几处用到了TEB中的变量,但其偏移在WinDbg中却没显示,可能是微软故意没公开,不知道有没有方法查看,或者直接告诉我这几处偏移的意义。
NtCurrentTeb() + 0x6D4
NtCurrentTeb() + 0x6E0