Jump to content
Tuts 4 You

dll unpack, GetThreadContext error... solution


langxang

Recommended Posts

Posted (edited)

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 BP1,BP2,BP3,BP4: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
.break
.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
.endif
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
assume esi:ptr IMAGE_IMPORT_DESCRIPTOR
mov dlls_imported,0
mov borland_flag,FALSE
mov redirection_flag,FALSE
@loop:
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
pushad
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
.endif
no_borland:
popad
.endif
sub eax,ImageBase
mov [esi].FirstThunk,eax
add esi,sizeof IMAGE_IMPORT_DESCRIPTOR
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
.endif
invoke ResumeThread,myThread
invoke Sleep,8
jmp @loop
@@:
call FixIAT
call NewPEinfo
.endif
@continue:
.endif
.elseif DBEvent.dwDebugEventCode == EXCEPTION_DEBUG_EVENT .endif
invoke ContinueDebugEvent,DBEvent.dwProcessId,DBEvent.dwThreadId,dwDebugOperation
.endw
@@exit:
invoke CloseHandle,myProcess
invoke CloseHandle,ProcessInfo.hThread
retProcessDll endp
Edited by langxang
Posted (edited)

Any of these tuts will help:

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

http://www.tuts4you.com/download.php?list.30

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

CreateToolhelp32Snapshot

Module32First

Module32Next

Have a look at:

CreateToolhelp32Snapshot

http://msdn.microsoft.com/en-us/library/aa911386.aspx

Cheers

Nacho_dj

Edited by Nacho_dj
Posted (edited)

loaddll source

start: 
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
.endif
mov al, byte ptr [esi+1]
inc esi
cmp al, 22h
jnz @b
@next:
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
@load:
invoke LoadLibraryEx,esi,NULL,DONT_RESOLVE_DLL_REFERENCES
.if eax==0
invoke MessageBox,0,CTEXT("Unable to load DLL"),0,MB_OK
invoke ExitProcess,0
.endif
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

loaddll.zip

Edited by langxang
Posted (edited)

I think I have found the solution.

dllunpack.zip

Edited by langxang

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...