源码
以_alldiv函数为例,为什么挑它呢? 因为他没有对数据引用,也没有全局变量导致重定位问题,纯机器码,用来测试我的“任意机器码转静态lib”最好不过
// CodeCopier.cpp : 定义控制台应用程序的入口点。
//
#include <windows.h>
#include <stdio.h>
#define BEA_ENGINE_STATIC
#define BEA_USE_STDCALL
#include "BeaEngine.h"
#pragma comment(lib,"BeaEngine.lib")
#define TYPE_I386 0x00000001
#define TYPE_AMD64 0x00000002
#define TYPE_EXE 0x00000100
#define TYPE_DLL 0x00000200
#define TYPE_SYS 0x00000400
#define TYPE_PE 0x00010000
#define TYPE_FILE 0x10000000//文件
#define TYPE_MEMMAP 0x20000000//文件内存映射代码
#define TYPE_MEM 0x40000000//纯内存代码
#define TYPE_FILE_DLL_X86 (TYPE_FILE | TYPE_PE | TYPE_DLL | TYPE_I386)
#include <vector>
using namespace std;
BOOL OpenPeByFileName(PCHAR FilePath, PVOID* OutBaseAddr)
{
if (!GetFileAttributesA(FilePath) & FILE_ATTRIBUTE_NORMAL)
return FALSE;
*OutBaseAddr = (PVOID)(((ULONG_PTR)LoadLibrary(FilePath)) & ~0xF);
return TRUE;
}
BOOL OpenCodeContainer(ULONG CodeType, PCHAR Name, ULONG Id, PVOID* OutBaseAddr)
{
switch (CodeType)
{
case TYPE_FILE_DLL_X86:
return OpenPeByFileName(Name, OutBaseAddr);
break;
default:
break;
}
return FALSE;
}
int GetFunctionLen(ULONG_PTR Begin)
{
DISASM disasm;
int sum = 0;
int len = 0, maxsize = 0xFFFF;
do
{
memset(&disasm, 0, sizeof(disasm));
disasm.EIP = (UIntPtr)Begin + (UIntPtr)sum;
len = Disasm(&disasm);
sum += len;
if (len > 0)
{
if (strstr(disasm.CompleteInstr, "ret"))
break;//发现ret指令则假设函数退出并以此推测函数大小和
}
} while (len > 0 && sum <= maxsize);
return sum;
}
BOOL WriteCodeToObj(HANDLE File, ULONG_PTR Begin, ULONG Len)
{
//1.构造section目录
//2.构造section内容,将各个section内部数据存储到lib中,lib的section的个数为导出符号数,导出地址需要适应IMAGE_SCN_ALIGN_??BYTES
//3.构造COFF Symbol Table
//4.加入导出符号名数组
std::vector<BYTE> filedata;
IMAGE_FILE_HEADER objheader;
int symbolnum = 0;
//加入文件头
memset(&objheader, 0, sizeof(objheader));
filedata.insert(filedata.end(), (BYTE*)&objheader, (BYTE*)(&objheader + 1));
//加入k个.text段
int secnum = 1;//要求dll输出最后一个为辅助函数
int offsetraw = sizeof(IMAGE_FILE_HEADER)+secnum * sizeof(IMAGE_SECTION_HEADER);//后置数据偏移
int offsetsymbol = 4;//符号字串偏移,之前有字串数DWORD
int index = 0;
symbolnum = secnum;
std::vector<BYTE> rawdata;//储存各个section指向的数据
std::vector<BYTE> symbolinfo;//存储COFF Symbol Table
std::vector<BYTE> functors;//存储符号名数组
IMAGE_SECTION_HEADER secheader;
memset(&secheader, 0, sizeof(secheader));
memcpy(secheader.Name, ".text", IMAGE_SIZEOF_SHORT_NAME);
secheader.SizeOfRawData = Len;
secheader.PointerToRawData = offsetraw ;
secheader.Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ;
secheader.PointerToRelocations = secheader.PointerToRawData + secheader.SizeOfRawData;
filedata.insert(filedata.end(), (BYTE*)&secheader, (BYTE*)(&secheader + 1));
//构造symboltable和section关联
IMAGE_SYMBOL symbol;
BYTE* funcname = (BYTE*)"_alldiv";
functors.insert(functors.end(),funcname,funcname+8);
memset(&symbol, 0, sizeof(symbol));
symbol.N.LongName[1] = offsetsymbol;
symbol.SectionNumber = index + 1;
symbol.Type = 0x20;// TYPE_FUNCTION
symbol.StorageClass = IMAGE_SYM_CLASS_EXTERNAL;
symbolinfo.insert(symbolinfo.end(), (BYTE*)&symbol, (BYTE*)(&symbol + 1));
filedata.insert(filedata.end(), (BYTE*)Begin,(BYTE*)Begin + Len);
//更新头部
IMAGE_FILE_HEADER* pobjheader = (IMAGE_FILE_HEADER*)filedata.data();
pobjheader->Machine = IMAGE_FILE_MACHINE_I386;
pobjheader->NumberOfSections = secnum;
pobjheader->PointerToSymbolTable = filedata.size();//计算符号表偏移
pobjheader->NumberOfSymbols = symbolnum;
//加入符号表
filedata.insert(filedata.end(), symbolinfo.begin(), symbolinfo.end());
//加入符号名数组个数
int strsize = functors.size() + 4;
filedata.insert(filedata.end(), (BYTE*)&strsize, (BYTE*)(&strsize + 1));
//加入符号名数组
filedata.insert(filedata.end(), functors.begin(), functors.end());
DWORD writenum;
WriteFile(File, filedata.data(), filedata.size(), &writenum, NULL);
return TRUE;
}
void main()
{
//第一步,打开文件或内存
PVOID BaseAddr = NULL;
ULONG BufSize;
OpenCodeContainer(TYPE_FILE_DLL_X86, "e:\\ntdll.dll", 0, &BaseAddr);;
HANDLE hObj = CreateFileA("alldiv.obj", GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
if (BaseAddr)
{
ULONG_PTR Begin = (ULONG_PTR)GetProcAddress((HMODULE)BaseAddr, "_alldiv");
int Len = GetFunctionLen(Begin);
WriteCodeToObj(hObj, Begin, Len);
}
CloseHandle(hObj);
}
生成obj结果
ext:00000000
.text:00000000 ; =============== S U B R O U T I N E =======================================
.text:00000000
.text:00000000
.text:00000000 public _alldiv
.text:00000000 _alldiv proc near
.text:00000000
.text:00000000 arg_0 = dword ptr 4
.text:00000000 arg_4 = dword ptr 8
.text:00000000 arg_8 = dword ptr 0Ch
.text:00000000 arg_C = dword ptr 10h
.text:00000000
.text:00000000 push edi
.text:00000001 push esi
.text:00000002 push ebx
.text:00000003 xor edi, edi
.text:00000005 mov eax, [esp+0Ch+arg_4]
.text:00000009 or eax, eax
.text:0000000B jge short loc_21
.text:0000000D inc edi
.text:0000000E mov edx, [esp+0Ch+arg_0]
.text:00000012 neg eax
.text:00000014 neg edx
.text:00000016 sbb eax, 0
.text:00000019 mov [esp+0Ch+arg_4], eax
.text:0000001D mov [esp+0Ch+arg_0], edx
.text:00000021
.text:00000021 loc_21: ; CODE XREF: _alldiv+Bj
.text:00000021 mov eax, [esp+0Ch+arg_C]
.text:00000025 or eax, eax
.text:00000027 jge short loc_3D
.text:00000029 inc edi
.text:0000002A mov edx, [esp+0Ch+arg_8]
.text:0000002E neg eax
.text:00000030 neg edx
.text:00000032 sbb eax, 0
.text:00000035 mov [esp+0Ch+arg_C], eax
.text:00000039 mov [esp+0Ch+arg_8], edx
.text:0000003D
.text:0000003D loc_3D: ; CODE XREF: _alldiv+27j
.text:0000003D or eax, eax
.text:0000003F jnz short loc_59
.text:00000041 mov ecx, [esp+0Ch+arg_8]
.text:00000045 mov eax, [esp+0Ch+arg_4]
.text:00000049 xor edx, edx
.text:0000004B div ecx
.text:0000004D mov ebx, eax
.text:0000004F mov eax, [esp+0Ch+arg_0]
.text:00000053 div ecx
.text:00000055 mov edx, ebx
.text:00000057 jmp short loc_9A
.text:00000059 ; ---------------------------------------------------------------------------
.text:00000059
.text:00000059 loc_59: ; CODE XREF: _alldiv+3Fj
.text:00000059 mov ebx, eax
.text:0000005B mov ecx, [esp+0Ch+arg_8]
.text:0000005F mov edx, [esp+0Ch+arg_4]
.text:00000063 mov eax, [esp+0Ch+arg_0]
.text:00000067
.text:00000067 loc_67: ; CODE XREF: _alldiv+71j
.text:00000067 shr ebx, 1
.text:00000069 rcr ecx, 1
.text:0000006B shr edx, 1
.text:0000006D rcr eax, 1
.text:0000006F or ebx, ebx
.text:00000071 jnz short loc_67
.text:00000073 div ecx
.text:00000075 mov esi, eax
.text:00000077 mul [esp+0Ch+arg_C]
.text:0000007B mov ecx, eax
.text:0000007D mov eax, [esp+0Ch+arg_8]
.text:00000081 mul esi
.text:00000083 add edx, ecx
.text:00000085 jb short loc_95
.text:00000087 cmp edx, [esp+0Ch+arg_4]
.text:0000008B ja short loc_95
.text:0000008D jb short loc_96
.text:0000008F cmp eax, [esp+0Ch+arg_0]
.text:00000093 jbe short loc_96
.text:00000095
.text:00000095 loc_95: ; CODE XREF: _alldiv+85j
.text:00000095 ; _alldiv+8Bj
.text:00000095 dec esi
.text:00000096
.text:00000096 loc_96: ; CODE XREF: _alldiv+8Dj
.text:00000096 ; _alldiv+93j
.text:00000096 xor edx, edx
.text:00000098 mov eax, esi
.text:0000009A
.text:0000009A loc_9A: ; CODE XREF: _alldiv+57j
.text:0000009A dec edi
.text:0000009B jnz short loc_A4
.text:0000009D neg edx
.text:0000009F neg eax
.text:000000A1 sbb edx, 0
.text:000000A4
.text:000000A4 loc_A4: ; CODE XREF: _alldiv+9Bj
.text:000000A4 pop ebx
.text:000000A5 pop esi
.text:000000A6 pop edi
.text:000000A7 retn 10h
.text:000000A7 _alldiv endp
.text:000000A7
.text:000000A7 _text ends
.text:000000A7
.text:000000A7
.text:000000A7 end