mov dwFunctionFound, 1 ;Set the value, for later .break .endif
add edi, sizeof IMAGE_THUNK_DATA ;Next thunk .endw
.if dwFunctionFound != 1 ;If the function wasn't found xor eax, eax ret ;Return 0 .endif
mov eax, 1 ret ;Return 1
;Success IATHook endp start:
invoke GetModuleHandle, addr szModule invoke GetProcAddress, eax, addr szTargetFunc
mov ebx, HookProc
invoke IATHook, addr szModule, eax, ebx ;Redirect GetForegroundWindow (eax) to HookProc (ebx) .if eax == 0
invoke MessageBox, NULL, addr szFail, addr szMsgTitle, MB_OK invoke ExitProcess, 0 .endif
;Is now hooked, hopefully.. so lets call it invoke GetForegroundWindow
invoke ExitProcess, 0 end start
(四)局限性:1当程序运用一种叫late-demand binding技术,函数被调用时才定位地址,这样以来就不能在IAT中定位目标函数地址了.2当目标程序用动态加载(LoadLibrary)时,这种方法也将失效.
二.Dll-Injecting
(一)通过注册表注入Dll
1.一般原理:Windows的注册表中有这样一个键值,
HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows\\AppInit_Dlls。在这个键下的值都会被系统的任何一个GUI程序所加载,其实就是只要程序调用了User32.dll,则User32.dll的DllMain函数在初始化时,会把这个键下的Dll自动加载,除非是命令行程序。记得求职信病毒用的就是这一招。
2.大体框架:这个方法要操作注册表,简要介绍一下几个主要的操作注册表的函数 RegCreateKeyEx: 创建一个子键 RegOpenKeyEx: 打开子键 RegQuetyValueEx:获取一个项的值 RegSetValueEx: 设置指定项的值 文件1: myHookDll {
特定目的的Dll } 文件2:
myHookDll.dll拷贝到系统目录 RegCreateKeyEx 创建AppInit_Dlls键 RegQuetyValueEx 获取这个项 找到myHookDll.dll路径
RegSetValueEx 把myHookDll.Dll设置成AppInit_Dlls 3.代码实例: #include
#pragma comment(linker, \ #pragma comment(linker, \ #pragma comment(linker, \
#define REGLOC _T(\
HHOOK g_hHook;
TCHAR g_szPath[MAX_PATH]; TCHAR g_szCurrent[0x1000]; HMODULE g_hInstance;
HKEY GetRegLoc()
{
HKEY hKey = 0;
RegCreateKeyEx(HKEY_LOCAL_MACHINE, REGLOC, 0, 0, 0, KEY_ALL_ACCESS, 0, &hKey, 0); return hKey; }
#pragma comment(linker, \ATE\ #pragma comment(linker, \ATE\
char *stristr(const char *String, const char *Pattern) {
char *pptr, *sptr, *start;
for (start = (char *)String; *start != 0; start++) {
// find start of pattern in string
for( ; ((*start!=0) && (toupper(*start) != toupper(*Pattern))); start++) ;
if(0 == *start) return NULL;
pptr = (char *)Pattern; sptr = (char *)start;
while(toupper(*sptr) == toupper(*pptr)) { sptr++; pptr++;
// if end of pattern then pattern was found if(0 == *pptr) return start; } }
return NULL; } //
// DllRegisterServer. //
STDAPI DllRegisterServer() {
HKEY hKey; DWORD type; DWORD len;
DWORD ret = E_UNEXPECTED;
if((hKey = GetRegLoc()) == 0) return E_UNEXPECTED;
// Get current AppInit_Dlls string
if(ERROR_SUCCESS == RegQueryValueEx(hKey, _T(\ {
// Make sure aren't already registered char *ptr = stristr(g_szCurrent, g_szPath); g_szCurrent[len] = 0;
if(g_szCurrent[0] != 0) lstrcat(g_szCurrent, _T(\
ret = S_OK;
// append our DLL path to the AppInit_Dlls path if(ptr == 0) {
lstrcat(g_szCurrent, g_szPath); len = lstrlen(g_szCurrent);
RegSetValueEx(hKey, _T(\ } }
RegCloseKey(hKey);
return ret; }
STDAPI DllUnregisterServer() {
HKEY hKey; DWORD type; DWORD len;
DWORD ret = E_UNEXPECTED;
if((hKey = GetRegLoc()) == 0) return E_UNEXPECTED;
// Get current AppInit_Dlls string
if(ERROR_SUCCESS == RegQueryValueEx(hKey, _T(\ {
// Find where our DLL path is stored char *ptr = stristr(g_szCurrent, g_szPath);
ret = S_OK;
if(ptr != 0) {
len = lstrlen(g_szPath);
if(ptr > 0 && ptr[-1] == ',') { ptr--; len++; }
memmove(ptr, ptr + len, lstrlen(g_szCurrent) - len + 1);
RegSetValueEx(hKey, _T(\ } }
RegCloseKey(hKey);
return S_OK; } //
// Computer-based training hook. Used to trap window creation // of a common dialog (Open/Save), so that the ListView contained // in these dialogs can be changed to report-view before it is displayed. //
static LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam) {
if(nCode == HCBT_CREATEWND) {
HWND hwnd = (HWND)wParam; HWND hwndParent;
CBT_CREATEWND *cw = (CBT_CREATEWND *)lParam;
TCHAR szClass[32];
GetClassName(hwnd, szClass, 32);

