Cracking a packed exe. _packer: azpack: _program: AZPR 2.31.
by staier
(September 1999)

projunpa
Packers

Courtesy of fravia's pages of reverse engineering ~ slightly edited by fravia+
Cracking a packed exe. _packer: azpack: _program: AZPR 2.31.
	After  investigating the program with softice,procdump and IDA we  easily can find that
the program 'd be cracked at once  , (if unpacked).But what if we can not unpack the 
program?-Actually i could not-.The first  way is to make a  little program, and  patch the
target with WriteProcessMemory .

here i show you the source in Pascal, wich could be  compiled in any DELPHI32.

LISTING 1 "AZPRLOADER.DPR"


program azprloader; uses windows;// WIN32 API headers i:cardinal; const buf:array[0..4 ]of byte=($0,$0,$90,$90,$e3); {codes buffer BUF[0..1]- read bytes accumulator BUF[2..3]- NOP NOP -opcodes for writing BUF[4] -amother patch- jmp addr correction} const appname='azpr.exe';// target name var //structures ,defined in windows.pas(windows.h) sti:_startupinfoa; lpPi:_process_information; begin if not CreateProcess(nil,AppName,nil,nil,false, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,//attributes nil,nil,StartupInfo,//applications params lpPI)//returning attributes then begin messageboxa(0,'cannot find AZPR.exe','AZPRloader',0);//// no such a file exit; end; while (true )do//endless cycle if readprocessmemory(lppi.hprocess,pointer($40fbb5),@buf,2,i) then //read bytes if (buf[0]=$eb) and (buf[1]=5) then//if the bytes already unpacked(Jnz +5) begin writeprocessmemory(lppi.hProcess,pointer($40fbb5),@buf[2],2,i);//change to NOP NOP writeprocessmemory(lppi.hProcess,pointer($40fb78),@buf[4],1,i);//another patch closehandle(lppi.hprocess);//Close process handle exit; end; end.

EOLISTING .1
actually the skeleton of the program was decompiled from TNO loader for aspack packer
Now i will describe another approach ,rather universal too,It can be applied to huge quantity of programs either packet or not. The approach can be expressed in short as an "installation of new thread, wich controls target's thread(s)"

First
We need to find some detales :Imagebase, GetModuleHandleA @ GepProcAddress addresses and "kernel32.dll" string address.All these detales we can clearly see in IDA exellent disassembler.

Second
let us start hiew, and find entrypoint and some space for new code. the space can be fount at the end of file at .0016A96E so at the entrypoint, let us write a jump to our new code

.169000 jmp .0016A96E. -instead of pushad ; call 00000000;

Third
Now,let us be a compiler(assembler).

As the imagebase of program is 400000 , then the program will hardly be relocated to another address, so we can hardcode absolute addresses,in other case we'd have to òî extend relocation table after coding.

LISTING 2 "putch for the AZPR.exex"


.0016A96E: B860E80000 mov eax,00000E860 ; restore code .0016A973: A300905600 mov [000569000],eax ; at the .0016A978: C6050590560000 mov b,[000569005],000; entrypoint .0016A97F: 689C975600 push 00056979C ;'kernel32.dll'. .0016A984: 90 nop .0016A985: FF1590975600 call d,[000569790] ;GetModuleHandleA('kernel32.dll'). .0016A98B: 50 push eax ;save handle of kernel32.dll. .0016A98C: 6A44 push 044 ;ordinal 0x44-CreateThread. .0016A98E: 90 nop ; .0016A98F: 50 push eax ;'kernel32.dll'. .0016A990: FF158C975600 call d,[00056978C] ;GepProcAddress(kernlhandle,0x44L). .0016A996: A3C7A95600 mov [00056A9C7],eax ;save address of CreateThread. .0016A99B: 58 pop eax ;restore handle of kernel32.dll. .0016A99C: 6A6D push 06D ;ordinal 0x44-ExitThread. .0016A99E: 50 push eax ;kernel32.dll .0016A99F: FF158C975600 call d,[00056978C] ;GepProcAddress(kernlhandle,0x6dL); .0016A9A5: A3CBA95600 mov [00056A9CB],eax ;save ExitThread address. .0016A9AA: 68CF975600 push 0005697CF ;address for dword,returned from CreateThread; .0016A9AF: 6A00 push 000 .0016A9B1: 6A00 push 000 .0016A9B3: 68D3A95600 push 00056A9D3 ;our thread function .0016A9B8: 6A00 push 000 .0016A9BA: 6A00 push 000 .0016A9BC: FF15C7A95600 call d,[00056A9C7] ;CreateThread(0,0,threadhandler,0,0,&returned); .0016A9C2: E939E6FFFF jmp .000169000 ;jump to restored code at the entrypoint .0016A9C7: 1111 adc [ecx],edx ;this is not a command ,DWORD - CreateThread address .0016A9C9: 1111 adc [ecx],edx ; .0016A9CB: 2222 and ah,[edx] ;this is not a command ,DWORD - ExitThread address .0016A9CD: 2222 and ah,[edx] ; .0016A9CF: 3333 xor esi,[ebx] ;this is not a command,DWORD -returned .0016A9D1: 3333 xor esi,[ebx] ; ;new thread procedure DWORD winapi threadproc(void*); .0016A9D3: 66813DB5FB4000EB05 cmp w,[00040FBB5],005EB ;if bytes unpacked .0016A9DC: 75F5 jne .00016A9D3 ;no, repeat cmp .0016A9DE: 66C705B5FB40009090 mov w,[00040FBB5],09090 ;patch teh program jmp +05 to NOP NOP .0016A9E7: C60578FB40003E mov b,[00040FB78],03E ;another jmp address .0016A9EE: 6A00 push 000 .0016A9F0: FF15CBA95600 call d,[00056A9CB] ;ExitÅhread(0); .0016A9F6: C20400 retn 00004 ;return that's all,falks
(c) 1999 Staier from http://staier.cjb.net
You are deep inside fravia's page of reverse engineering, choose your way out:
redhomepage redlinks redsearch_forms red+ORC redhow to protect redacademy database
redreality cracking redhow to search redjavascript wars
redtools redanonymity academy redcocktails redantismut CGI-scripts redmail_fravia+
redIs reverse engineering legal?