update to ida 7.6, add builds
This commit is contained in:
113
idasdk76/plugins/uunp/uunp.idc
Normal file
113
idasdk76/plugins/uunp/uunp.idc
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
|
||||
This is a reimplementation of the uunp universal unpacker in IDC.
|
||||
It illustrates the use of the new debugger functions in IDA v5.2
|
||||
|
||||
*/
|
||||
|
||||
#include <idc.idc>
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static main()
|
||||
{
|
||||
auto ea, bptea, tea1, tea2, code, minea, maxea, r_esp, r_eip, caller, funcname;
|
||||
|
||||
// Calculate the target IP range. It is the first segment.
|
||||
// As soon as the EIP register points to this range, we assume that
|
||||
// the unpacker has finished its work.
|
||||
tea1 = get_first_seg();
|
||||
tea2 = get_segm_end(tea1);
|
||||
|
||||
// Calculate the current module boundaries. Any calls to GetProcAddress
|
||||
// outside of these boundaries will be ignored.
|
||||
minea = get_inf_attr(INF_MIN_EA);
|
||||
maxea = get_inf_attr(INF_MAX_EA);
|
||||
|
||||
// Use win32 local debugger
|
||||
load_debugger("win32", 0);
|
||||
|
||||
// Launch the debugger and run until the entry point
|
||||
if ( !run_to(get_inf_attr(INF_START_EA)) )
|
||||
return Failed(-10);
|
||||
|
||||
// Wait for the process to stop at the entry point
|
||||
code = wait_for_next_event(WFNE_SUSP, -1);
|
||||
if ( code <= 0 )
|
||||
return Failed(code);
|
||||
|
||||
// Set a breakpoint at GetProcAddress
|
||||
bptea = get_name_ea_simple("kernel32_GetProcAddress");
|
||||
if ( bptea == BADADDR )
|
||||
return warning("Could not locate GetProcAddress");
|
||||
add_bpt(bptea);
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
// resume the execution and wait until the unpacker calls GetProcAddress
|
||||
code = wait_for_next_event(WFNE_SUSP|WFNE_CONT, -1); // CONT means resume
|
||||
if ( code <= 0 )
|
||||
return Failed(code);
|
||||
|
||||
// check the caller, it must be from our module
|
||||
r_esp = get_reg_value("ESP");
|
||||
caller = get_wide_dword(r_esp);
|
||||
if ( caller < minea || caller >= maxea )
|
||||
continue;
|
||||
|
||||
// if the function name passed to GetProcAddress is not in the ignore-list,
|
||||
// then switch to the trace mode
|
||||
funcname = get_strlit_contents(get_wide_dword(r_esp+8), -1, STRTYPE_C);
|
||||
// ignore some api calls because they might be used by the unpacker
|
||||
if ( funcname == "VirtualAlloc" )
|
||||
continue;
|
||||
if ( funcname == "VirtualFree" )
|
||||
continue;
|
||||
|
||||
// A call to GetProcAddress() probably means that the program has been
|
||||
// unpacked in the memory and now is setting up its import table
|
||||
break;
|
||||
}
|
||||
|
||||
// trace the program in the single step mode until we jump to
|
||||
// the area with the original entry point.
|
||||
del_bpt(bptea);
|
||||
enable_tracing(TRACE_STEP, 1);
|
||||
for ( code = wait_for_next_event(WFNE_ANY|WFNE_CONT, -1); // resume
|
||||
code > 0;
|
||||
code = wait_for_next_event(WFNE_ANY, -1) )
|
||||
{
|
||||
r_eip = get_event_ea();
|
||||
if ( r_eip >= tea1 && r_eip < tea2 )
|
||||
break;
|
||||
}
|
||||
if ( code <= 0 )
|
||||
return Failed(code);
|
||||
|
||||
// as soon as the current ip belongs OEP area, suspend the execution and
|
||||
// inform the user
|
||||
suspend_process();
|
||||
code = wait_for_next_event(WFNE_SUSP, -1);
|
||||
if ( code <= 0 )
|
||||
return Failed(code);
|
||||
|
||||
enable_tracing(TRACE_STEP, 0);
|
||||
|
||||
// Clean up the disassembly so it looks nicer
|
||||
del_items(tea1, DELIT_EXPAND|DELIT_DELNAMES, tea2-tea1);
|
||||
create_insn(r_eip);
|
||||
auto_mark_range(tea1, tea2, AU_USED);
|
||||
auto_mark_range(tea1, tea2, AU_FINAL);
|
||||
take_memory_snapshot(1);
|
||||
set_name(r_eip, "real_start");
|
||||
warning("Successfully traced to the completion of the unpacker code\n"
|
||||
"Please rebuild the import table using renimp.idc\n"
|
||||
"before stopping the debugger");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Print an failure message
|
||||
static Failed(code)
|
||||
{
|
||||
warning("Failed to unpack the file, sorry (code %d)", code);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user