// aspr.pas : Plugin for ImpREC to find asprotect 1.2x real API in its wrapped code //////////////////////////////////////////////////////////////////////////////////////////// // // Note that this example is not a tracer but just an opcode checker. // //////////////////////////////////////////////////////////////////////////////////////////// library aspr; uses windows; // Global variables //////////////////////////////////////////////////////////////////////////////////////////// // None // Exported function to use // // Parameters: // ----------- // : HANDLE of the mapped file // : Size of that mapped file // : TimeOut of ImpREC in Options // : Pointer to trace (in VA) // : EIP of the exact call (in VA) // // Returned value: // --------------- // Use a value greater or equal to 200. It will be shown by ImpREC if no output were created function Trace(hFileMap:DWORD; dwSizeMap:DWORD; dwTimeOut:DWORD; dwToTrace:DWORD; dwExactCall:DWORD) : DWORD;cdecl; var to_trace : array[0..15] of BYTE; i : DWORD; val : DWORD; address : PDWORD; found : BOOLEAN; dwPtrOutput : PDWORD; begin // Map the view of the file dwPtrOutput := PDWORD(MapViewOfFile(hFileMap, 6, 0, 0, 0)); if (DWORD(dwPtrOutput) = 0) then begin // Can't map view Trace := 201; exit; end; // Check the size of the map file if (dwSizeMap < 4) then begin // Invalid map size UnmapViewOfFile(pointer(dwPtrOutput)); CloseHandle(hFileMap); Trace := 203; exit; end; // Check if we read a valid pointer if (IsBadReadPtr(pointer(dwToTrace), 4)) then begin // Bad pointer! UnmapViewOfFile(pointer(dwPtrOutput)); CloseHandle(hFileMap); Trace := 205; exit; end; movememory(addr(to_trace),pointer(dwToTrace),16); //all different types of redirection code, a common one is mov eax,[xxxxxx]. //check for this and the value at xxxxxx and try to guess it ;) val := 0; found := false; for i := 0 to 9 do begin if to_trace[i] = $A1 then begin //check all the possible mov eax,[xxxxxx] redirections address := pointer((@to_trace[i+1])^); val := address^; //val = eax returned by redirection code. try to id emulated function if val = GetVersion then begin val := dword(GetProcAddress(GetModuleHandle('KERNEL32.DLL'),'GetVersion')); found := true; end; if val = dword(GetCommandLineA) then begin val := dword(GetProcAddress(GetModuleHandle('KERNEL32.DLL'),'GetCommandLineA')); found := true; end; if val = GetCurrentProcess then begin val := dword(GetProcAddress(GetModuleHandle('KERNEL32.DLL'),'GetCurrentProcess')); found := true; end; if val = GetCurrentProcessID then begin val := dword(GetProcAddress(GetModuleHandle('KERNEL32.DLL'),'GetCurrentProcessId')); found := true; end; end; if (to_trace[i]=$FF) and (to_trace[i+1]=$35) and (to_trace[i+6]=$58) then begin //check all the possible mov eax,[xxxxxx] redirections address := pointer((@to_trace[i+2])^); val := address^; //val = eax returned by redirection code. try to id emulated function if val = GetVersion then begin val := dword(GetProcAddress(GetModuleHandle('KERNEL32.DLL'),'GetVersion')); found := true; end; if val = dword(GetCommandLineA) then begin val := dword(GetProcAddress(GetModuleHandle('KERNEL32.DLL'),'GetCommandLineA')); found := true; end; if val = GetCurrentProcess then begin val := dword(GetProcAddress(GetModuleHandle('KERNEL32.DLL'),'GetCurrentProcess')); found := true; end; if val = GetCurrentProcessID then begin val := dword(GetProcAddress(GetModuleHandle('KERNEL32.DLL'),'GetCurrentProcessId')); found := true; end; end; end; //check for ret 4 at certain position (lock/free resource) if (to_trace[4]=$C2) and (to_trace[5]=$04) then begin val := dword(GetProcAddress(GetModuleHandle('KERNEL32.DLL'),'FreeResource')); found := true; end; //check for call and ret 4 at certain position (freeresource->getversion) if (to_trace[3]=$E8) and (to_trace[10]=$04) then begin val := dword(GetProcAddress(GetModuleHandle('KERNEL32.DLL'),'FreeResource')); found := true; end; //check for lockresource if (to_trace[8]=$8B) and (to_trace[10]=$08) and (to_trace[11]=$5D) then begin val := dword(GetProcAddress(GetModuleHandle('KERNEL32.DLL'),'LockResource')); found := true; end; //check for mov eax,[xxxxxx] and ret 4 at certain position (lockresource) if (to_trace[3]=$8B) and (to_trace[7]=$C2) then begin val := dword(GetProcAddress(GetModuleHandle('KERNEL32.DLL'),'LockResource')); found := true; end; //check for GetProcAddress if (to_trace[5]=$C) and (to_trace[8]=$8) then begin val := dword(GetProcAddress(GetModuleHandle('KERNEL32.DLL'),'GetProcAddress')); found := true; end; //check for GetModuleHandle if (to_trace[5]=$8) and (to_trace[15]=$EB) then begin val := dword(GetProcAddress(GetModuleHandle('KERNEL32.DLL'),'GetModuleHandleA')); found := true; end; //check for DialogBoxParamA if (to_trace[6]=$8) and (to_trace[9]=$18) then begin val := dword(GetProcAddress(GetModuleHandle('USER32.DLL'),'DialogBoxParamA')); found := true; end; if found then begin dwPtrOutput^ := val; // OK Trace := 200; end else Trace := 300; //completed, but nothing found UnmapViewOfFile(pointer(dwPtrOutput)); CloseHandle(hFileMap); end; exports Trace; begin // Initialize all you need end.