update to ida 7.6, add builds
This commit is contained in:
172
idasdk76/plugins/uunp/win9x.cpp
Normal file
172
idasdk76/plugins/uunp/win9x.cpp
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
This file contains Win9x (95, 98) specific stuff.
|
||||
|
||||
It can be safely ignored if you are only interested in XP systems.
|
||||
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <ida.hpp>
|
||||
#include <idp.hpp>
|
||||
#include <dbg.hpp>
|
||||
|
||||
#include "uunp.hpp"
|
||||
|
||||
#pragma pack(push, 1)
|
||||
//lint --e{958} Padding required
|
||||
struct push_insn_t
|
||||
{
|
||||
BYTE push; // must be 0x68
|
||||
DWORD ea;
|
||||
};
|
||||
|
||||
//lint -estring(958,member) padding is required to align members
|
||||
struct push_jump_insns_t
|
||||
{
|
||||
BYTE push; // must be 0x68
|
||||
DWORD ea;
|
||||
BYTE jmp; // must be 0xE9
|
||||
DWORD reloff; //lint !e754 not referenced
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// find the address of the thunk for GetProcessAddress() under Windows 9x
|
||||
void uunp_ctx_t::win9x_resolve_gpa_thunk()
|
||||
{
|
||||
DWORD off;
|
||||
|
||||
ea_t ea = curmod.start_ea + offsetof(IMAGE_DOS_HEADER, e_lfanew);
|
||||
if ( read_dbg_memory(ea, &off, sizeof(off)) != sizeof(off) )
|
||||
return;
|
||||
|
||||
#define _OI offsetof(IMAGE_NT_HEADERS32, OptionalHeader.DataDirectory[ \
|
||||
IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
|
||||
if ( read_dbg_memory((DWORD)curmod.start_ea + off + _OI, &off, sizeof(off)) != sizeof(off) )
|
||||
return;
|
||||
#undef _OI
|
||||
|
||||
IMAGE_IMPORT_DESCRIPTOR imp;
|
||||
DWORD hK32 = DWORD(size_t(GetModuleHandle("kernel32")));
|
||||
|
||||
bool found = false;
|
||||
for ( off += (DWORD)curmod.start_ea;
|
||||
read_dbg_memory(off, &imp, sizeof(imp)) == sizeof(imp) && imp.Name;
|
||||
off += sizeof(imp) )
|
||||
{
|
||||
if ( imp.ForwarderChain == hK32 )
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( found )
|
||||
{
|
||||
DWORD tmp;
|
||||
for ( off = imp.FirstThunk + (DWORD)curmod.start_ea;
|
||||
read_dbg_memory(off, &tmp, sizeof(tmp)) == sizeof(tmp) && tmp != 0;
|
||||
off += sizeof(DWORD) )
|
||||
{
|
||||
if ( tmp >= hK32 )
|
||||
continue; // for TH_xxx entries
|
||||
|
||||
push_insn_t thunk;
|
||||
if ( read_dbg_memory(tmp, &thunk, sizeof(thunk)) != sizeof(thunk)
|
||||
|| thunk.push != 0x68 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if ( thunk.ea == bp_gpa )
|
||||
{
|
||||
bp_gpa = tmp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// find all dwords equal to 'ea' and remember their translations
|
||||
// search in the current module
|
||||
static bool calc_thunk_target(uunp_ctx_t &ctx, uint32 ea32, uint32 imp32)
|
||||
{
|
||||
bool matched = false;
|
||||
|
||||
for ( ea_t pos = ctx.curmod.start_ea;
|
||||
pos <= ctx.curmod.end_ea;
|
||||
pos += sizeof(DWORD) )
|
||||
{
|
||||
pos = bin_search2(pos, ctx.curmod.end_ea, (uchar *)&ea32, NULL,
|
||||
4, BIN_SEARCH_NOBREAK|BIN_SEARCH_CASE|BIN_SEARCH_FORWARD);
|
||||
if ( pos == BADADDR )
|
||||
break;
|
||||
if ( pos & 3 )
|
||||
continue;
|
||||
|
||||
flags_t F = get_flags(pos);
|
||||
if ( is_tail(F) )
|
||||
continue;
|
||||
|
||||
matched = true;
|
||||
ctx.thunks[pos] = imp32;
|
||||
}
|
||||
return matched;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// find Windows 9x import thunk
|
||||
static bool resolve_thunk(uunp_ctx_t &ctx, ea_t ea)
|
||||
{
|
||||
push_jump_insns_t thunk;
|
||||
|
||||
if ( get_bytes(&thunk, sizeof(thunk), ea) != sizeof(thunk)
|
||||
|| thunk.push != 0x68 || thunk.jmp != 0xE9
|
||||
|| thunk.ea < 0x80000000 || thunk.ea >= 0xC0000000 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !calc_thunk_target(ctx, uint32(ea), thunk.ea) )
|
||||
msg("%a: Thunked import (%08a) without references\n", ea, ea_t(thunk.ea));
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Windows 9x: find thunked imports and their targets
|
||||
void uunp_ctx_t::find_thunked_imports()
|
||||
{
|
||||
if ( (DWORD)bp_gpa & 0xF )
|
||||
{
|
||||
warning("Non-standard thunk address");
|
||||
return;
|
||||
}
|
||||
|
||||
// find the thunk area for our module
|
||||
invalidate_dbgmem_contents(curmod.start_ea, curmod.end_ea); // for bin-search
|
||||
invalidate_dbgmem_contents(0x80000000, 0xC0000000);
|
||||
|
||||
for ( ea_t ea = bp_gpa; ea > 0x80000000; ea -= 0x10 )
|
||||
{
|
||||
if ( !resolve_thunk(*this, ea) )
|
||||
break;
|
||||
}
|
||||
|
||||
for ( ea_t ea = bp_gpa + 0x10; ea < 0xC0000000; ea += 0x10 )
|
||||
{
|
||||
if ( !resolve_thunk(*this, ea) )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( thunks.empty() )
|
||||
warning("Could not find thunk area");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
ea_t uunp_ctx_t::win9x_find_thunk(ea_t ea)
|
||||
{
|
||||
thunks_t::iterator p = thunks.find(ea);
|
||||
ea_t func = p != thunks.end() ? p->second : get_dword(ea);
|
||||
return func;
|
||||
}
|
||||
Reference in New Issue
Block a user