Hey guys,
Just playing around with asm and trying to learn things about retrieving the module base of a dll loaded in memory.
Although I succesfully managed to retrieve the modulebase of the dll I want to retrieve the base from I noticed some weird memory leak. Although I think it's because of this function:
This source has been posted on the net I just applied it for me to play with and noticed the weird behaviour of my memory when using this function. It retrieves the imagebase perfectly but my memory keeps going up and up.
GetModuleBaseAddress PROC iProcID:DWORD, DLLName:DWORD
LOCAL hSnap:DWORD
LOCAL xModule:MODULEENTRY32
mov eax, [iProcID]
mov eax, [eax]
invoke CreateToolhelp32Snapshot, TH32CS_SNAPMODULE, eax
mov hSnap,eax
mov xModule.dwSize, sizeof xModule
invoke Module32First, hSnap, addr xModule
test eax, eax
jnz getdll
mov eax, 0
ret
getdll:
invoke Module32Next, hSnap, addr xModule
test eax, eax
jnz checkdll
mov eax, 0
ret
checkdll:
invoke lstrcmpi, DLLName, addr xModule.szModule
test eax, eax
jnz getdll
mov eax, xModule.modBaseAddr
ret
GetModuleBaseAddress ENDP
thanks in advance
You have to close the handle of your snapshot...
invoke CloseHandle, hSnap
Here's a couple of functions I wrote to demonstrate finding a module using an address. Since they reside inside a library there are a few checks and also the functions are loaded dynamically in order to avoid errors when run on different Windows versions so the two can reside in the same program and be selected based on OS version.
For 9x
GetModuleByAddr9x FRAME Address,pModuleName
LOCAL pID :D
LOCAL hSnap :D
LOCAL me32 :MODULEENTRY32
LOCAL hlib :D
LOCAL pCreateToolhelp32Snapshot :D
LOCAL pModule32First :D
LOCAL pModule32Next :D
mov D[me32.dwSize],SIZEOF MODULEENTRY32
invoke IsBadWritePtr,[pModuleName],1
or eax,eax
jz >
xor eax,eax
dec eax
ret
:
invoke GetModuleHandleA,"Kernel32.dll"
mov [hlib],eax
or eax,eax
jnz >
dec eax
ret
:
mov [hlib],eax
invoke GetProcAddress,[hlib],"CreateToolhelp32Snapshot"
mov [pCreateToolhelp32Snapshot],eax
or eax,eax
jnz >
dec eax
ret
:
invoke GetProcAddress,[hlib],"Module32First"
mov [pModule32First],eax
or eax,eax
jnz >
dec eax
ret
:
invoke GetProcAddress,[hlib],"Module32Next"
mov [pModule32Next],eax
or eax,eax
jnz >
dec eax
ret
:
mov eax,[pModuleName]
mov B[eax],0
invoke GetCurrentProcessId
mov [pID],eax
push [pID]
push 8 ;TH32CS_SNAPMODULE
call [pCreateToolhelp32Snapshot]
mov [hSnap],eax
push offset me32
push [hSnap]
call [pModule32First]
jmp >L2
L1:
mov eax,[me32.modBaseAddr]
mov ecx,[me32.modBaseSize]
add ecx,eax
cmp [Address],eax
jb >
cmp [Address],ecx
ja >
invoke lstrcpyA,[pModuleName],OFFSET me32.szModule
jmp >.DONE
:
push offset me32
push [hSnap]
call [pModule32Next]
L2:
or eax,eax
jnz <L1
.DONE
invoke CloseHandle,[hSnap]
invoke lstrlenA,[pModuleName]
or eax,eax // Set the flags
RET
ENDF
For NT
GetModuleByAddrNT FRAME Address,pModuleName
uses edi,esi,ebx
LOCAL pID :D
LOCAL hProcess :D
LOCAL hMods[1024] :D
LOCAL cbNeeded :D
LOCAL modinfo :MODULEINFO
LOCAL hModule :D
LOCAL hlib :D
LOCAL pEnumProcessModules :D
LOCAL pGetModuleInformation :D
LOCAL ModName[MAX_PATH] :B
invoke IsBadWritePtr,[pModuleName],1
or eax,eax
jz >
xor eax,eax
dec eax
ret
:
invoke LoadLibraryA,"psapi.dll"
or eax,eax
jnz >
dec eax
ret
:
mov [hlib],eax
invoke GetProcAddress,[hlib],"EnumProcessModules"
mov [pEnumProcessModules],eax
or eax,eax
jnz >
invoke FreeLibrary,[hlib]
xor eax,eax
dec eax
ret
:
invoke GetProcAddress,[hlib],"GetModuleInformation"
mov [pGetModuleInformation],eax
or eax,eax
jnz >
invoke FreeLibrary,[hlib]
xor eax,eax
dec eax
ret
:
mov eax,[pModuleName]
mov B[eax],0
mov ebx,[Address]
invoke GetCurrentProcessId
mov [pID],eax
invoke OpenProcess,PROCESS_QUERY_INFORMATION+PROCESS_VM_READ,FALSE,[pID]
mov [hProcess],eax
or eax,eax
jnz >
invoke FreeLibrary,[hlib]
xor eax,eax
dec eax
ret
:
push offset cbNeeded
push 1024
push offset hMods
push [hProcess]
call [pEnumProcessModules]
or eax,eax
jz >>.DONE
mov edi,[cbNeeded]
shr edi,2
mov esi,offset hMods
L1:
mov eax,[esi]
mov [hModule],eax
add esi,4
push SIZEOF MODULEINFO
push offset modinfo
push [hModule]
push [hProcess]
call [pGetModuleInformation]
or eax,eax
jz >.DONE
cmp ebx,[modinfo.lpBaseOfDll]
jg >L2
dec edi
or edi,edi
js >.DONE
jmp <L1
L2:
mov eax,[modinfo.SizeOfImage]
add eax,[modinfo.lpBaseOfDll]
cmp ebx,eax
jl >L3
dec edi
or edi,edi
js >.DONE
jmp <L1
L3:
invoke GetModuleFileNameA,[hModule],OFFSET ModName,256
invoke GetFileTitleA,OFFSET ModName,[pModuleName],256
.DONE
invoke CloseHandle,[hProcess]
invoke FreeLibrary,[hlib]
invoke lstrlenA,[pModuleName]
test eax,eax // Set the flags
RET
ENDF
Thanks for the reply donkey, everything is working perfect now. :dance: