元始天尊 发表于 2015-11-16 00:49:41

提取动态链接库ntdll的函数到静态lib

本帖最后由 元始天尊 于 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 = 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 ptr4
.text:00000000 arg_4         = dword ptr8
.text:00000000 arg_8         = dword ptr0Ch
.text:00000000 arg_C         = dword ptr10h
.text:00000000
.text:00000000               push    edi
.text:00000001               push    esi
.text:00000002               push    ebx
.text:00000003               xor   edi, edi
.text:00000005               mov   eax,
.text:00000009               or      eax, eax
.text:0000000B               jge   short loc_21
.text:0000000D               inc   edi
.text:0000000E               mov   edx,
.text:00000012               neg   eax
.text:00000014               neg   edx
.text:00000016               sbb   eax, 0
.text:00000019               mov   , eax
.text:0000001D               mov   , edx
.text:00000021
.text:00000021 loc_21:                                 ; CODE XREF: _alldiv+Bj
.text:00000021               mov   eax,
.text:00000025               or      eax, eax
.text:00000027               jge   short loc_3D
.text:00000029               inc   edi
.text:0000002A               mov   edx,
.text:0000002E               neg   eax
.text:00000030               neg   edx
.text:00000032               sbb   eax, 0
.text:00000035               mov   , eax
.text:00000039               mov   , 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,
.text:00000045               mov   eax,
.text:00000049               xor   edx, edx
.text:0000004B               div   ecx
.text:0000004D               mov   ebx, eax
.text:0000004F               mov   eax,
.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,
.text:0000005F               mov   edx,
.text:00000063               mov   eax,
.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   
.text:0000007B               mov   ecx, eax
.text:0000007D               mov   eax,
.text:00000081               mul   esi
.text:00000083               add   edx, ecx
.text:00000085               jb      short loc_95
.text:00000087               cmp   edx,
.text:0000008B               ja      short loc_95
.text:0000008D               jb      short loc_96
.text:0000008F               cmp   eax,
.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即可

niling 发表于 2015-11-19 00:46:18

不错,这收藏了,以后想静态链接就爽多了!

besteast 发表于 2015-11-25 16:51:00

:lol:lol:lol:lol:lol:lol:lol:lol:lol
页: [1]
查看完整版本: 提取动态链接库ntdll的函数到静态lib