Hi!

I'm having a problem with API hooking, but! This problem appears only when I'm loading taskmgr.exe myseft... If the taskmgr.exe already loaded - everything goes as I need.

Here are the functions.

First, dll injection code:


InjectLib Proc dwProcessId:DWORD, lpszLibFile:DWORD
LOCAL dwMemSize,
dwWritten,
dwKernel,
dwProcAddr,
dwThread,
Result,
pszRemote :DWORD

LOCAL hProcess :HANDLE

invoke OpenProcess, PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or PROCESS_VM_WRITE, TRUE, dwProcessId
.if eax
mov Result, FALSE

mov hProcess, eax

mov eax, @Result(lstrlen, lpszLibFile)
inc eax
mov dwMemSize, eax
invoke VirtualAllocEx, hProcess, NULL, eax, MEM_COMMIT, PAGE_READWRITE;
.if eax
mov pszRemote, eax
invoke WriteProcessMemory, hProcess, pszRemote, lpszLibFile, dwMemSize, ADDR dwWritten
.if eax
mov dwKernel, @Result(GetModuleHandle, @Text('KERNEL32'))
mov dwProcAddr, @Result(GetProcAddress, dwKernel, @Text('LoadLibraryA'));
invoke CreateRemoteThread, hProcess, NULL, 0, dwProcAddr, pszRemote, 0, NULL
.if eax
mov dwThread, eax
mov Result, TRUE
invoke WaitForSingleObject, dwThread, INFINITE
invoke CloseHandle, dwThread
.endif
.endif
invoke VirtualFreeEx, hProcess, pszRemote, 0, MEM_RELEASE
.endif
.endif
mov eax, Result
Ret
InjectLib Endp


Second, creating the process and injecting my library:


CreateProcessEx Proc Param1:DWORD, Param2:DWORD, Param3:DWORD, Param4:DWORD, Param5:DWORD, Param6:DWORD, \
Param7:DWORD, Param8:DWORD, Param9:DWORD, Param10:DWORD, lpszLibFile :DWORD

mov eax, Param6
or eax, CREATE_SUSPENDED
invoke CreateProcess, Param1, Param2, Param3, Param4, Param5, eax, Param7, Param8, Param9, Param10

push eax
push ebx
mov ebx, Param10

invoke InjectLib, [ebx+8], lpszLibFile
invoke ResumeThread, [ebx+4]

pop ebx
pop eax
Ret
CreateProcessEx Endp


Third, IAT entries patching... From my DLL.


ReplaceIATEntryInOneMod Proc USES Ebx lpszCaleeName:DWORD, lpfnCurrent:DWORD, lpfnNew:DWORD, hmodCaller:DWORD

LOCAL hHandle:DWORD
LOCAL Dummy :DWORD
LOCAL ppfn :DWORD
LOCAL wrbt :DWORD

invoke ImageDirectoryEntryToData, hmodCaller, TRUE, \
IMAGE_DIRECTORY_ENTRY_IMPORT, ADDR hHandle

.if eax == NULL
jmp _exit
.endif

xchg Ebx, Eax
@AssumePtr IMAGE_IMPORT_DESCRIPTOR
.while [ebx].Name1
mov Eax, (IMAGE_IMPORT_DESCRIPTOR Ptr [Ebx]).Name1
add Eax, hmodCaller
invoke lstrcmpi, Eax, lpszCaleeName
.if eax == 0
jmp _found
.else
add Ebx, SIZEOF IMAGE_IMPORT_DESCRIPTOR
.endif
.endw
jmp _exit

_found:
mov Ebx, [ebx].FirstThunk
add Ebx, hmodCaller

@AssumePtr IMAGE_THUNK_DATA
.while [ebx].u1.Function
mov eax, [Ebx].u1.Function
.if lpfnCurrent == eax
lea ebx, [ebx].u1.Function
mov ppfn, ebx
invoke VirtualProtect, ppfn, SIZEOF DWORD, PAGE_EXECUTE_READWRITE, ADDR Dummy
mov hHandle, @Result(GetCurrentProcess)
invoke WriteProcessMemory, hHandle, ppfn, ADDR lpfnNew, SIZEOF DWORD, ADDR wrbt
jmp _exit

invoke VirtualProtect, ppfn, SIZEOF DWORD, Dummy, ADDR Dummy
.endif

add Ebx, SIZEOF IMAGE_THUNK_DATA
.endw
jmp _exit

_exit:
Assume Ebx:Nothing
ret
ReplaceIATEntryInOneMod Endp

ReplaceIATEntryInAllMod Proc Restore:BYTE

LOCAL hSnap :DWORD
LOCAL hProcSnap :MODULEENTRY32

mov hProcSnap.dwSize, SIZEOF MODULEENTRY32
invoke GetCurrentProcessId
invoke CreateToolhelp32Snapshot, TH32CS_SNAPMODULE, eax
mov hSnap, eax
invoke Module32First, hSnap, ADDR hProcSnap
.if eax
.repeat
mov eax, hProcSnap.hModule
.if eax
.if !Restore
invoke ReplaceIATEntryInOneMod, ADDR szKernel, oldOpenProc, ADDR NewOpen, hProcSnap.hModule ; OpenProcess
invoke ReplaceIATEntryInOneMod, ADDR szKernel, oldKillProc, ADDR NewKill, hProcSnap.hModule ; TerminateProcess
invoke ReplaceIATEntryInOneMod, ADDR szKernel, oldGetProc, ADDR NewProc, hProcSnap.hModule ; GetProcAddress
.else
invoke ReplaceIATEntryInOneMod, ADDR szKernel, ADDR NewProc, oldGetProc, hProcSnap.hModule ; GetProcAddress
invoke ReplaceIATEntryInOneMod, ADDR szKernel, ADDR NewKill, oldKillProc, hProcSnap.hModule ; TerminateProcess
invoke ReplaceIATEntryInOneMod, ADDR szKernel, ADDR NewOpen, oldOpenProc, hProcSnap.hModule ; TerminateProcess
.endif
.endif
invoke Module32Next, hSnap, ADDR hProcSnap
.until !eax
.endif
invoke CloseHandle, hSnap
ret
ReplaceIATEntryInAllMod Endp

DllEntry Proc hInstDll:HINSTANCE, reason:DWORD, reserved1:DWORD

.if reason == DLL_PROCESS_ATTACH
mov dwKernel, @Result(GetModuleHandle, ADDR szKernel)
mov oldGetProc, @Result(GetProcAddress, dwKernel, @Text('GetProcAddress'))
mov oldKillProc, @Result(GetProcAddress, dwKernel, @Text('TerminateProcess'))
mov oldOpenProc, @Result(GetProcAddress, dwKernel, @Text('OpenProcess'))

invoke ReplaceIATEntryInAllMod, FALSE
[ ... ]

.elseif reason == DLL_PROCESS_DETACH
invoke ReplaceIATEntryInAllMod, TRUE

[ ... ]


And the last, replaced functions


; New TerminateProcess
NewKill Proc Param1:DWORD, Param2:DWORD

push Param2
push Param1
call oldKillProc
Ret
NewKill EndP

; New OpenProcess
NewOpen Proc Param1:DWORD, Param2:DWORD, Param3:DWORD

push Param3
push Param2
push Param1
call oldOpenProc
Ret
NewOpen EndP

; New GetProcAddress
NewProc Proc hModule:DWORD, lpProc:DWORD

push lpProc
push hModule
call oldGetProc

.if eax == oldGetProc
mov eax, OFFSET NewProc

.elseif eax == oldKillProc
mov eax, OFFSET NewKill

.elseif eax == oldOpenProc
mov eax, OFFSET NewOpen
.endif
Ret
NewProc EndP


Maybe some one would look through the code and say me where am I wrong...

Thanx...
Posted on 2004-03-17 20:19:17 by The CHEMI$T
afaik no IAT when u just create it
i'd do hard hook on those API instead of IAT redirect
Posted on 2004-03-18 05:38:23 by comrade