Jump to content
Tuts 4 You

dll unpack, GetThreadContext error... solution


Recommended Posts

Here is a unpacker for PECompact packed dll, but there are some error occur:

1、CreateProcess use command line: loaddll.exe *.dll (just like ollydbg)

2、While CREATE_PROCESS_DEBUG_EVENT,log the DBEvent.u.CreateProcessInfo.hProcess and DBEvent.u.CreateProcessInfo.hThread

3、While LOAD_DLL_DEBUG_EVENT, when load *.dll, SuspendThread DBEvent.u.CreateProcessInfo.hThread, than set breakpoint in OEP,and ResumeThread DBEvent.u.CreateProcessInfo.hThread, while GetThreadContext, Context.regEip always stop in ntdll.KiFastSystemCallRet, can not get dll's regEip:

ProcessDll proc
LOCAL Buffer [64]:byte
LOCAL BP1_data,BP2_data,BP3_data,BP4_data:DWORD
LOCAL hProcess:dword
LOCAL tempaddr:dword
LOCAL dlls_imported,PatchAddr:dword
LOCAL szContext[1024]:byte
LOCAL TEB,LDR:dword mov flag,0
invoke GetTempPath, sizeof TempPath, addr TempPath
invoke wsprintf,addr OutBuff,addr Format,addr loaddllPath,addr FilePath;loaddll.exe 2.dll
invoke GetStartupInfo,addr startinfo
invoke CreateProcess,NULL,addr OutBuff,NULL,NULL,FALSE,DEBUG_PROCESS+DEBUG_ONLY_THIS_PROCESS ,NULL,addr TempPath,addr startinfo,addr ProcessInfo
.while TRUE
invoke WaitForDebugEvent,addr DBEvent,INFINITE
mov dwDebugOperation,DBG_CONTINUE
.if DBEvent.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT
invoke OutputInfo,CTEXT("Exit Debug"),0
.elseif DBEvent.dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT
mov edx,DBEvent.u.CreateProcessInfo.hProcess
mov myProcess,edx
mov ecx,DBEvent.u.CreateProcessInfo.hThread
mov myThread,ecx
.elseif DBEvent.dwDebugEventCode == LOAD_DLL_DEBUG_EVENT
mov Context.ContextFlags,CONTEXT_FULL
invoke GetThreadContext,myThread,addr Context
invoke GetThreadSelectorEntry,myThread,Context.regFs,addr ldte
mov ah,[ldte.HighWord1.Bytes.BaseHi]
shl eax,16
mov ax,[ldte.BaseLow]
assume fs:nothing
mov eax,fs:[18h]
mov eax,[eax+30h] mov eax,DBEvent.u.LoadDll.lpBaseOfDll
mov dwModBase,eax
.if dwModBase < 60000000h
invoke ReadProcessMemory,myProcess,DBEvent.u.LoadDll.lpImageName,addr OutBuff,4,NULL
mov eax,dword ptr OutBuff
invoke ReadProcessMemory,myProcess,eax,addr pDllName,256,NULL
invoke Unicode2Ansi,addr pDllName,addr outinf
invoke lstrcmp,addr outinf,addr FilePath
.if eax==0
inc flag
invoke wsprintf,addr OutBuff,CTEXT("LoadDll sucess: handle:%08Xh,base:%08Xh,name:%s",13,10,0),DBEvent.u.LoadDll.hFile,DBEvent.u.LoadDll.lpBaseOfDll,addr outinf
invoke OutputInfo,addr OutBuff,0
mov esi,DBEvent.u.LoadDll.lpBaseOfDll
mov DllBase,esi
mov eax,DBEvent.u.LoadDll.hFile
mov hDll,eax
.elseif flag==1
mov edi,DllBase
add edi,EntryPiont
add edi,1
lea esi,Buffer
invoke ReadProcessMemory,myProcess,edi,esi,4,0
mov edi,dword ptr [esi]
invoke wsprintf,addr OutBuff,CTEXT("%s: %.08X",13,10,0),CTEXT("Got the address of mov eax,xxxxxxxx "),edi
invoke OutputInfo,addr OutBuff,0
invoke Searchcode,myProcess,edi,0ffd7h
.if eax==0
invoke MessageBox,0,CTEXT("Searchcode Error"),0,MB_OK
jmp @@exit
mov BP1,eax
invoke ReadProcessMemory,myProcess,BP1,addr BP1_data,2,0
invoke WriteProcessMemory,myProcess,BP1,CTEXT(0EBh,0FEh),2,0
invoke wsprintf,addr OutBuff,CTEXT("%s: %.08X",13,10,0),CTEXT("Set Breakpoint in 'CALL EDI' "),BP1
invoke OutputInfo,addr OutBuff,0
invoke Searchcode,myProcess,BP1,0FFe0h
mov BP2,eax
invoke wsprintf,addr OutBuff,CTEXT("%s: %.08X",13,10,0),CTEXT("Set Breakpoint in 'JMP EAX' "),BP2
invoke OutputInfo,addr OutBuff,0
invoke ReadProcessMemory,myProcess,BP2,addr BP2_data,2,0
invoke WriteProcessMemory,myProcess,BP2,CTEXT(0CCh,00h),2,0
_10MB equ 1024*1024*10
invoke VirtualAlloc,0,_10MB,MEM_COMMIT,PAGE_READWRITE
mov pNewImports,eax
invoke OutputInfo,CTEXT("Start Unpacking...",13,10,0),0
invoke ResumeThread,myThread
invoke Sleep,100
mov esi,pNewImports
mov dlls_imported,0
mov borland_flag,FALSE
mov redirection_flag,FALSE
invoke SuspendThread,myThread
mov Context.ContextFlags,CONTEXT_FULL
invoke GetThreadContext,myThread,addr Context
;Error here, Context.regEip=ntdll.KiFastSystemCallRet always
mov eax,Context.regEip
.if eax==BP1
invoke WriteProcessMemory,myProcess,BP1,addr BP1_data,2,0
mov eax,Context.regEdi
mov tempaddr,eax
invoke Searchcode,myProcess,eax,5751h
add eax,3
mov ebx,eax
mov BP3,ebx
invoke ReadProcessMemory,myProcess,BP3,addr BP3_data,2,0
invoke WriteProcessMemory,myProcess,ebx,CTEXT(0EBh,0FEh),2,0
add ebx,6
mov BP4,ebx
invoke ReadProcessMemory,myProcess,BP4,addr BP4_data,2,0
invoke Searchcode,myProcess,tempaddr,4040h
invoke Searchcode,myProcess,tempaddr,8902h
add eax,1
mov PatchAddr,eax
invoke WriteProcessMemory,myProcess,eax,CTEXT(16h),1,0
.elseif eax==BP3
invoke WriteProcessMemory,myProcess,BP3,addr BP3_data,2,0
invoke WriteProcessMemory,myProcess,BP4,CTEXT(0EBh,0FEh),2,0
mov eax,Context.regEcx
sub eax,DllBase
mov [esi].Name1,eax
mov eax, Context.regEdi
.if borland_flag!=TRUE
invoke ReadProcessMemory,myProcess,Context.regEdi,addr Buffer,4,0
.if Buffer!=0
mov ebx,PatchAddr
sub ebx,3
invoke WriteProcessMemory,myProcess,ebx,CTEXT(90h,90h,90h,90h),4,0
mov borland_flag,TRUE
invoke OutputInfo,CTEXT("Borland stuff detected - inject code",13,10,0),0
sub eax,ImageBase
mov [esi].FirstThunk,eax
inc dlls_imported
.elseif eax==BP4
invoke WriteProcessMemory,myProcess,BP4,addr BP4_data,2,0
invoke WriteProcessMemory,myProcess,BP3,CTEXT(0EBh,0FEh),2,0
.elseif eax==BP2
invoke WriteProcessMemory,myProcess,BP2,addr BP2_data,2,0
invoke wsprintf,addr OutBuff,CTEXT("Set BreakPoint in %.08X ",13,10,0),BP2
invoke OutputInfo,addr OutBuff,0
mov eax,Context.regEax
invoke wsprintf,addr OutBuff,CTEXT("%s: %.08X",13,10,0),CTEXT(13,10,"Find OEP"),eax
invoke OutputInfo,addr OutBuff,0
invoke MessageBox,0,addr OutBuff,CTEXT("Got OEP"),MB_OK
jmp @f
invoke ResumeThread,myThread
invoke Sleep,8
jmp @loop
call FixIAT
call NewPEinfo
.elseif DBEvent.dwDebugEventCode == EXCEPTION_DEBUG_EVENT .endif
invoke ContinueDebugEvent,DBEvent.dwProcessId,DBEvent.dwThreadId,dwDebugOperation
invoke CloseHandle,myProcess
invoke CloseHandle,ProcessInfo.hThread
retProcessDll endp
Edited by langxang
Link to comment

Any of these tuts will help:

Portable Executable Format (PE) [ The analysis and understanding of the structure and makeup of executable modules... ]


If you need to retrieve the base address of a loaded module, then you should use:




Have a look at:





Edited by Nacho_dj
Link to comment

loaddll source

invoke GetModuleHandle,0
mov hInstance,eax
invoke GetCommandLine
mov esi,eax
inc esi
cmp al, 22h
je @next
.if al==0
invoke MessageBox,0,CTEXT("Missing DLL name"),0,MB_OK
invoke ExitProcess,0
mov al, byte ptr [esi+1]
inc esi
cmp al, 22h
jnz @b
mov al, byte ptr [esi+1]
inc esi
cmp al, 20h
jnz @load
mov al, byte ptr [esi+1]
inc esi
cmp al, 20h
je @b
.if eax==0
invoke MessageBox,0,CTEXT("Unable to load DLL"),0,MB_OK
invoke ExitProcess,0
mov DllBase,eax
invoke ImageNtHeader,DllBase
mov edi,eax
assume edi:ptr IMAGE_NT_HEADERS
mov eax,[edi].OptionalHeader.AddressOfEntryPoint
add eax,DllBase
mov EP,eax
mov ecx,[edi].OptionalHeader.SizeOfImage
mov SizeOfImage,ecx
mov edi,DllBase
mov esi,EP
movzx edx, byte ptr [esi]
mov byte ptr [esi],0CCh
call EP
invoke ExitProcess,NULLend start


Edited by langxang
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Create New...