-
-
[原创]未知壳乱序重构
-
发表于:
2008-1-15 19:44
7379
-
很有趣
/*
Coder: dummyz@126.com
*/
#include <Windows.h>
#include <fstream>
#include <memory>
#include <list>
#include <algorithm>
#include "xde.h"
using namespace std;
typedef unsigned char ubyte;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
ubyte* load_pefile(const char* fname, ulong& size)
{
IMAGE_DOS_HEADER dosheader;
IMAGE_NT_HEADERS ntheader;
ifstream ifile(fname, ios::binary);
if ( !ifile )
return NULL;
ifile.read((char*)&dosheader, sizeof (IMAGE_DOS_HEADER));
if ( dosheader.e_magic != IMAGE_DOS_SIGNATURE )
return NULL;
ifile.seekg(dosheader.e_lfanew, ios::beg);
ifile.read((char*)&ntheader, sizeof (IMAGE_NT_HEADERS));
if ( ntheader.Signature != IMAGE_NT_SIGNATURE ||
ntheader.FileHeader.NumberOfSections == 0 )
return NULL;
size = ifile.seekg(0, ios::end).tellg();
ifile.seekg(0, ios::beg);
auto_ptr<ubyte> buf(new ubyte[size]);
ifile.read((char*)buf.get(), size);
return buf.release();
}
typedef struct _instr
{
ubyte* old_ip;
ubyte* new_ip;
xde_instr instr;
} instr_t;
bool is_hasip(list<instr_t>& instr_lst, ubyte* ip)
{
list<instr_t>::iterator i = instr_lst.begin();
while ( i != instr_lst.end() )
{
instr_t& p = *i++;
if ( p.old_ip == ip )
{
return true;
}
}
return false;
}
int main(int argc, char* argv[])
{
if ( argc < 2 )
{
return -1;
}
ulong file_size;
auto_ptr<ubyte> file_buf(load_pefile(argv[1], file_size));
ubyte* base = file_buf.get();
if ( base == NULL )
{
return -2;
}
list<instr_t> instr_lst; // 指令表
list<ubyte*> ep_list; // 入口表
instr_t instr;
PIMAGE_DOS_HEADER dosheader = (PIMAGE_DOS_HEADER)base;
PIMAGE_NT_HEADERS ntheader = (PIMAGE_NT_HEADERS)(base + dosheader->e_lfanew);
PIMAGE_SECTION_HEADER sectheader = IMAGE_FIRST_SECTION(ntheader);
ulong code_size = ntheader->OptionalHeader.SizeOfCode;
ulong code_va = ntheader->OptionalHeader.ImageBase + sectheader->VirtualAddress;
ulong oep_va = ntheader->OptionalHeader.ImageBase + ntheader->OptionalHeader.AddressOfEntryPoint;
ubyte* code = base + sectheader->VirtualAddress;
instr.old_ip = base + ntheader->OptionalHeader.AddressOfEntryPoint - \
sectheader->VirtualAddress + sectheader->PointerToRawData;
auto_ptr<byte> code_buf(new byte[code_size * 2]);
memset(code_buf.get(), 0x90, code_size * 2);
instr.new_ip = code_buf.get() + ntheader->OptionalHeader.AddressOfEntryPoint - \
sectheader->VirtualAddress;
// @1 重构串行指令序
ep_list.push_back(instr.old_ip);
while ( true )
{
list<ubyte*>::iterator it;
printf("\r\bPasering eip = %08X...", instr.old_ip - code + code_va);
if (
instr.old_ip > code + code_size ||
is_hasip(instr_lst, instr.old_ip) // 检查是否已经处理过了, 从入口表中取出新的地址
)
{
if ( ep_list.empty() )
break;
instr.old_ip = ep_list.front();
ep_list.erase(ep_list.begin());
}
if ( 0 == xde_disasm(instr.old_ip, &instr.instr) )
{
printf("xde_disasm error!\n");
break;
}
/*
0040102C > $ C705 00104000>mov dword ptr [401000], 00401333
00401036 . FF25 00104000 jmp dword ptr [401000]
*/
if ( instr.instr.opcode == 0xc7 &&
instr.instr.modrm == 0x05 &&
(instr.instr.addr_l[0] >= code_va && instr.instr.addr_l[0] < oep_va)
)
{
ubyte* next_ep_ip = instr.old_ip + instr.instr.len;
if ( *(ushort*)next_ep_ip == 0x25ff &&
*(ulong*)(next_ep_ip + 2) == instr.instr.addr_l[0]
)
{
next_ep_ip += 6;
if ( ep_list.end() == find(ep_list.begin(), ep_list.end(), next_ep_ip) &&
!is_hasip(instr_lst, next_ep_ip)
)
{
ep_list.push_back(next_ep_ip);
}
instr.old_ip = instr.instr.data_l[0] - code_va + code;
continue;
}
}
if ( instr.instr.flag & C_REL )
{
ubyte* next_ep_ip = instr.old_ip + instr.instr.len;
switch ( instr.instr.datasize )
{
case 1: next_ep_ip = (ubyte*)((ulong)next_ep_ip + (long)instr.instr.data_c[0]); break;
case 4: next_ep_ip = (ubyte*)((ulong)next_ep_ip + (long)instr.instr.data_l[0]); break;
default: printf("error datasize!\n");
}
if ( ep_list.end() == find(ep_list.begin(), ep_list.end(), next_ep_ip) &&
!is_hasip(instr_lst, next_ep_ip)
)
{
ep_list.push_back(next_ep_ip);
}
if ( instr.old_ip[0] == 0x8a )
{
instr.old_ip[0] = 0x8a;
}
}
it = find(ep_list.begin(), ep_list.end(), instr.old_ip);
if ( ep_list.end() != it ) // 从入口表中踢出
{
ep_list.erase(it);
}
instr_lst.push_back(instr);
instr.new_ip += instr.instr.len;
if ( instr.old_ip[0] == 0xc3 ||
instr.old_ip[0] == 0xc2
)
{
if ( ep_list.empty() )
break;
instr.old_ip = ep_list.front();
ep_list.erase(ep_list.begin());
}
else
{
instr.old_ip += instr.instr.len;
}
}
printf("\ninstr sum = %d\n", instr_lst.size());
// @2 拷贝 & 校正偏移
list<instr_t>::iterator instr_lst_i = instr_lst.begin();
while ( instr_lst_i != instr_lst.end() )
{
instr_t& instr1 = *instr_lst_i++;
printf("\r\bRelocing eip = %08X...", instr1.new_ip - code_buf.get() + code_va);
if ( instr1.instr.flag & C_REL )
{
ubyte* jmp_ip = instr1.old_ip + instr1.instr.len;
switch ( instr1.instr.datasize )
{
case 1: jmp_ip = (ubyte*)((ulong)jmp_ip + (long)instr1.instr.data_c[0]); break;
case 4: jmp_ip = (ubyte*)((ulong)jmp_ip + (long)instr1.instr.data_l[0]); break;
default: printf("error datasize!\n");
}
do
{
if ( jmp_ip[0] == 0xc7 && jmp_ip[1] == 0x05 &&
*(ulong*)(jmp_ip + 2) >= code_va && *(ulong*)(jmp_ip + 2) < oep_va
)
{
if ( *(ushort*)(jmp_ip + 2 + 4 + 4) == 0x25ff &&
*(ulong*)(jmp_ip + 2 + 4 + 4 + 2) == *(ulong*)(jmp_ip + 2) )
{
jmp_ip = *(ulong*)(jmp_ip + 2 + 4) - code_va + code;
continue;
}
}
break;
} while( true );
list<instr_t>::iterator instr_lst_j = instr_lst.begin();
while ( instr_lst_j != instr_lst.end() )
{
instr_t& instr2 = *instr_lst_j;
if ( instr2.old_ip == jmp_ip )
{
xde_instr tmp = instr1.instr;
tmp.data_l[0] = instr2.new_ip - instr1.new_ip + instr1.instr.len;
xde_asm(instr1.new_ip, &tmp); // 汇编
break;
}
instr_lst_j++;
}
if ( instr_lst_j == instr_lst.end() )
{
printf("reloc jmp error!\n");
break;
}
}
else
{
memcpy(instr1.new_ip, instr1.old_ip, instr1.instr.len);
}
}
ofstream ofile("1.bin", ios::binary);
ofile.write((char*)code_buf.get(), code_size);
printf("\nFinished!\n");
return 0;
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课