- UID
- 2
- 精华
- 积分
- 7736
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
本帖最后由 元始天尊 于 2015-11-21 00:32 编辑
以_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
复制代码
另附lib解压obj大法:
保存以下代码到1.bat
for %%i in (*.lib) do (
for /f %%j in ('lib /nologo /list %%i') do (
echo %%j
lib /nologo /extract:%%j %%i
)
)
设置lib.exe到环境变量path中,命令行定位到lib目录,执行1.bat即可
|
|