代码:
很有趣:eek: /* 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; }