修改静态库

0)  背景

  有个静态库叫做 slib.lib, 其中包含两个 obj 文件:

    expofunc1.obj
        |- void sayHello1() { printf("Hello 1
"); }
        |- void sayWorld1() {}

    expofunc2.obj
        |- void sayHello2() { printf("Hello 2
"); }

    

  修改 sayHello1, 使输出无效 -- 即不会打印出 "Hello 1"。

一  拆分静态库成obj

1) 把 static lib 拆成 obj:

[cmd]>lib /list slib.lib >slib.txt

  生成文本 : slib.txt:

Microsoft (R) Library Manager Version 9.00.21022.08
Copyright (C) Microsoft Corporation. All rights reserved.

.Debugstdafx.obj
.DebugexpoFunc1.obj
.DebugexpoFunc2.obj

2) 编辑文本 slib.txt:

lib slib.lib /EXTRACT:.DebugexpoFunc1.obj
lib slib.lib /EXTRACT:.DebugexpoFunc2.obj

3)  修改 slib.txt 为 slib.bat

4) 执行 slib.bat


从 slib.lib 里提取出:

expofunc1.obj
expofunc2.obj

查看 expofunc1.obj 涉及到的符号:

dumpbin expofunc1.obj /symbols

二   关注obj

5)  dump oxpofunc1.obj

dumpbin expofunc1.obj /all > expofunc1_DMP.txt

打开 expofunc1_DMP.txt, 搜索 "sayHello1", 结构如下:

            SECTION HEADER #31
           .text name
               0 physical address
               0 virtual address
              49 size of raw data
            4CFD file pointer to raw data (00004CFD to 00004D45)
            4D46 file pointer to relocation table
               0 file pointer to line numbers
               4 number of relocations
               0 number of line numbers
        60501020 flags
                 Code
                 COMDAT; sym= "void __cdecl sayHello1(void)" (?sayHello1@@YAXXZ)
                 16 byte align
                 Execute Read

        RAW DATA #31
          00000000: 55 8B EC 81 EC C0 00 00 00 53 56 57 8D BD 40 FF  U.ì.ìà...SVW.?@?
          00000010: FF FF B9 30 00 00 00 B8 CC CC CC CC F3 AB 8B F4  ??10...?ììììó?.?
          00000020: 68 00 00 00 00 FF 15 00 00 00 00 83 C4 04 3B F4  h....?......?.;?
          00000030: E8 00 00 00 00 5F 5E 5B 81 C4 C0 00 00 00 3B EC  è...._^[.?à...;ì
          00000040: E8 00 00 00 00 8B E5 5D C3                       è.....?]?

        RELOCATIONS #31
                                                        Symbol    Symbol
         Offset    Type              Applied To         Index     Name
         --------  ----------------  -----------------  --------  ------
         00000021  DIR32                      00000000        CB  ??_C@_08LDIBCFKO@Hello?51?6?$AA@ (`string')
         00000027  DIR32                      00000000        C7  __imp__printf
         00000031  REL32                      00000000        CC  __RTC_CheckEsp
         00000041  REL32                      00000000        CC  __RTC_CheckEsp

这里每个函数对应一个 SECTION.
这里 sayHello1 处于 SECTION HEADER #31, 看一下 RELOCATIONS #31, 这里是 SECTION HEADER #31 引用的符号, 由于没有到 link 阶段, 所以这些符号的地址未知.

        00000027  DIR32                      00000000        C7  __imp__printf    // 表示 RAW DATA #31 段的offset 0x27 部分引用了 __imp__printf, 
                                                // 看一下 RAW DATA #31:
00000020: 68 00 00 00 00 FF 15 00 00 00 00 83 C4 04 3B F4 h....?......?.;? ^^^^^^^^^^^   这 4 个byte 就应该是 __imp__printf 的地址, 在 link 阶段当 __imp__printf 地址确定下来, __imp__printf 的真实地址会填充 00 00 00 00   "FF 15" 是 call 指令的机器码, 如果要让 __imp__printf 无效, 直接跳过这个函数就行, (__imp__printf 是 __cdel call, 不用管 stack 的平衡),    把 "FF 15" 修改成为 "EB 04" 即可。"EB 04" 是向前 jmp 4 byte 的机器码, 这个可以直接跳到 call __imp__printf 下一条指令.

 

三 修改obj

使用 notepad++ 的 HEX-Editor 插件

四 把修改后的的 obj 重新打包成静态库

[cmd]>lib /OUT:slib.lib expofunc1.obj expofunc2.obj

生成 slib.lib 就是被修改后的静态库.

原文地址:https://www.cnblogs.com/happylong/p/4320765.html