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

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

源码

  以_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