添加部分。启动应用程序时出错 (0xc000007b)

逆向工程 聚乙烯 部分
2021-07-03 01:25:07

我在此可执行文件的
外部链接中添加了一个部分,以
使用 cff 资源管理器从 windows xp 下载它是 winmine
的可执行文件,对可执行文件所做的唯一修改是添加一个我尚未手动编辑可执行文件的部分,否则 cff 资源管理器成功添加了该部分

但是如果我执行生成的可执行文件

我收到一个错误:

“启动应用程序时出错 (0xc000007b) ...”

我想了解为什么修改后的应用程序崩溃

在此处输入图片说明

2个回答

blabb的答案可能是正确的,只要它涉及到什么是错在编辑二进制文件,但建议使用内核调试器,找到问题的堆栈方式偏离航向。

对于本演示,我使用的是 Windows XP 而不是像您一样的 7。除了 XP 上的 NTSTATUS0xC0000135而不是0xC000007B.

我们打开 WinDbg 并执行二进制文件:

Microsoft (R) Windows Debugger Version 6.12.0002.633 X86
Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: "C:\Documents and Settings\Administrator\My Documents\Downloads\Winmine - XP - копия.exe"
Symbol search path is: *** Invalid ***
****************************************************************************
* Symbol loading may be unreliable without a symbol search path.           *
* Use .symfix to have the debugger choose a symbol path.                   *
* After setting your symbol path, use .reload to refresh symbol locations. *
****************************************************************************
Executable search path is: 
ModLoad: 01000000 01021000   winmine.exe
ModLoad: 7c900000 7c9b2000   ntdll.dll
ModLoad: 7c800000 7c8f6000   C:\WINDOWS\system32\kernel32.dll

弹出一个消息框:

在此处输入图片说明

我们不会关闭消息框。相反,我们打破了 WinDbg:

Break-in sent, waiting 30 seconds...
WARNING: Break-in timed out, suspending.
         This is usually caused by another thread holding the loader lock
(b58.e64): Wake debugger - code 80000007 (first chance)
eax=c0000135 ebx=00000000 ecx=00000a2b edx=00090608 esi=7ffdfc00 edi=c0000135
eip=7c90e514 esp=0006f6f0 ebp=0006f7d4 iopl=0         nv up ei pl nz na po cy
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000203
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for ntdll.dll - 
ntdll!KiFastSystemCallRet:
7c90e514 c3              ret

是的,它实际上需要这 30 秒。

让我们看看堆栈:

0:000> ~* k

.  0  Id: b58.e64 Suspend: 1 Teb: 7ffdf000 Unfrozen
ChildEBP RetAddr  
WARNING: Stack unwind information not available. Following frames may be wrong.
0006f7d4 7c91c880 ntdll!KiFastSystemCallRet
0006fa34 7c9246f2 ntdll!LdrDisableThreadCalloutsForDll+0xce
0006fa78 7c92469b ntdll!sprintf+0x13e
0006fa98 7c9247d5 ntdll!sprintf+0xe7
0006fb14 7c920244 ntdll!sprintf+0x221
0006fc94 7c91fad7 ntdll!RtlInitMemoryStream+0x2e8
0006fd1c 7c90e457 ntdll!RtlLookupElementGenericTable+0x80
00000000 00000000 ntdll!KiUserApcDispatcher+0x7

   1  Id: b58.324 Suspend: 1 Teb: 7ffde000 Unfrozen
ChildEBP RetAddr  
WARNING: Stack unwind information not available. Following frames may be wrong.
0028fc98 7c901046 ntdll!KiFastSystemCallRet
0028fd18 7c90e457 ntdll!RtlEnterCriticalSection+0x46
00000000 00000000 ntdll!KiUserApcDispatcher+0x7

第二个线程可能用于与 CSRSS 通信以显示消息或类似的东西,它并不是很有趣。第一个线程很重要,它的符号都是乱七八糟的。

让我们解决这个问题:

0:000> lm
start    end        module name
01000000 01021000   winmine    (deferred)             
7c800000 7c8f6000   kernel32   (deferred)             
7c900000 7c9b2000   ntdll      (export symbols)       C:\WINDOWS\system32\ntdll.dll
0:000> .symfix+
0:000> .reload /f
Reloading current modules
...
0:000> lm
start    end        module name
01000000 01021000   winmine    (pdb symbols)          C:\Documents and Settings\Administrator\Desktop\debugger_x86\sym\winmine.pdb\3B7D84751\winmine.pdb
7c800000 7c8f6000   kernel32   (pdb symbols)          C:\Documents and Settings\Administrator\Desktop\debugger_x86\sym\kernel32.pdb\A02FC3EC19B4474FB75641AF4C5B031C2\kernel32.pdb
7c900000 7c9b2000   ntdll      (pdb symbols)          C:\Documents and Settings\Administrator\Desktop\debugger_x86\sym\ntdll.pdb\CEFC0863B1F84130A11E0F54180CD21A2\ntdll.pdb
0:000> k
ChildEBP RetAddr  
0006f6ec 7c90d9ca ntdll!KiFastSystemCallRet
0006f6f0 7c9423a9 ntdll!NtRaiseHardError+0xc
0006f7d4 7c91c880 ntdll!LdrpMapDll+0x1b8
0006fa34 7c9246f2 ntdll!LdrpLoadImportModule+0x174
0006fa78 7c92469b ntdll!LdrpHandleOneNewFormatImportDescriptor+0x53
0006fa98 7c9247d5 ntdll!LdrpHandleNewFormatImportDescriptors+0x20
0006fb14 7c920244 ntdll!LdrpWalkImportDescriptor+0x19e
0006fc94 7c91fad7 ntdll!LdrpInitializeProcess+0xe1c
0006fd1c 7c90e457 ntdll!_LdrpInitialize+0x183
00000000 00000000 ntdll!KiUserApcDispatcher+0x7

您将获得与 blabb 几乎相同的堆栈,无需任何内核调试。太棒了,即使我自己这么说。

顺便说一句,第二个线程的堆栈仍然无趣:

0:000> ~1 k
ChildEBP RetAddr  
0028fc0c 7c90df5a ntdll!KiFastSystemCallRet
0028fc10 7c919b23 ntdll!NtWaitForSingleObject+0xc
0028fc98 7c901046 ntdll!RtlpWaitForCriticalSection+0x132
0028fca0 7c924d2d ntdll!RtlEnterCriticalSection+0x46
0028fd18 7c90e457 ntdll!_LdrpInitialize+0xf0
00000000 00000000 ntdll!KiUserApcDispatcher+0x7

我们可以查看这些函数的参数,并在绑定的导入表中看到问题:

0:000> kb
ChildEBP RetAddr  Args to Child              
0006f6ec 7c90d9ca 7c9423a9 c0000135 00000002 ntdll!KiFastSystemCallRet
0006f6f0 7c9423a9 c0000135 00000002 00000003 ntdll!NtRaiseHardError+0xc
0006f7d4 7c91c880 00020498 7ffdfc00 00000000 ntdll!LdrpMapDll+0x1b8
0006fa34 7c9246f2 00020498 010002ab 01000000 ntdll!LdrpLoadImportModule+0x174
0006fa78 7c92469b 7ffd6000 00020498 00191ee0 ntdll!LdrpHandleOneNewFormatImportDescriptor+0x53
0006fa98 7c9247d5 7ffd6000 00020498 00191ee0 ntdll!LdrpHandleNewFormatImportDescriptors+0x20
0006fb14 7c920244 00020498 00191ee0 7ffdf000 ntdll!LdrpWalkImportDescriptor+0x19e
0006fc94 7c91fad7 0006fd30 7c900000 0006fce0 ntdll!LdrpInitializeProcess+0xe1c
0006fd1c 7c90e457 0006fd30 7c900000 00000000 ntdll!_LdrpInitialize+0x183
00000000 00000000 00000000 00000000 00000000 ntdll!KiUserApcDispatcher+0x7
0:000> du 7ffdfc00 
7ffdfc00  "NEL32.dll"
0:000> db 010002ab
010002ab  4e 45 4c 33 32 2e 64 6c-6c 00 47 44 49 33 32 2e  NEL32.dll.GDI32.
010002bb  64 6c 6c 00 55 53 45 52-33 32 2e 64 6c 6c 00 53  dll.USER32.dll.S
010002cb  48 45 4c 4c 33 32 2e 64-6c 6c 00 57 49 4e 4d 4d  HELL32.dll.WINMM
010002db  2e 64 6c 6c 00 43 4f 4d-43 54 4c 33 32 2e 64 6c  .dll.COMCTL32.dl
010002eb  6c 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  l...............
010002fb  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0100030b  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0100031b  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................

如果您想跟踪加载过程而不是仅在失败后查看堆栈,您也可以使用用户模式调试器来完成。

让我们关闭消息框,并告诉 WinDbg 在进程创建时中断,而不是在静态导入解决后才发生的所谓的初始断点处

0:000> sxe cpr
0:000> .restart
CommandLine: "C:\Documents and Settings\Administrator\My Documents\Downloads\Winmine - XP - копия.exe"
Symbol search path is: srv*
Executable search path is: 
eax=01003e21 ebx=7ffd4000 ecx=7c910060 edx=7c90e920 esi=0078c60c edi=00ecf554
eip=7c810735 esp=0006fffc ebp=7c91005d iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00000200
7c810735 ??              ???
0:000> lm
start    end        module name
01000000 01021000   winmine    (deferred)             
0:000> k
ChildEBP RetAddr  
WARNING: Frame IP not in any known module. Following frames may be wrong.
0006fff8 00000000 0x7c810735

天哪这是什么?!winmine加载?但是我们知道ntdll从一开始就映射到每个 Win32 进程中。

嗯,ntdll实际上是映射的,但是调试器仍然没有得到关于它的调试事件。这就是我们在流程初始化过程中的早期阶段。

我们可以通过使用sxe ld ntdll(或sxe ld)来等待这个事件,或者我们可以强制 WinDbg 被通知ntdll然后我们可以在ntdll!LdrpHandleOneNewFormatImportDescriptor上放置断点

0:000> sxe ld ntdll
0:000> g
ModLoad: 7c900000 7c9b2000   ntdll.dll
eax=01003e21 ebx=7ffd4000 ecx=7c910060 edx=7c90e920 esi=0078c60c edi=00ecf554
eip=7c810735 esp=0006fffc ebp=7c91005d iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00000200
7c810735 ??              ???
0:000> lm
start    end        module name
01000000 01021000   winmine    (deferred)             
7c900000 7c9b2000   ntdll      (deferred)             
0:000> .symfix+
0:000> .reload /f
Reloading current modules
..
0:000> bu ntdll!LdrpHandleOneNewFormatImportDescriptor
0:000> bl
 0 e 7c9246ad     0001 (0001)  0:**** ntdll!LdrpHandleOneNewFormatImportDescriptor
0:000> g
Breakpoint 0 hit
eax=0006faac ebx=7ffd4000 ecx=000000b4 edx=0000415c esi=01000248 edi=00000001
eip=7c9246ad esp=0006fa7c ebp=0006fa98 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
ntdll!LdrpHandleOneNewFormatImportDescriptor:
7c9246ad 8bff            mov     edi,edi

这里绝对不需要内核调试。
我们需要的一切都可以从用户模式获得。

您的 exe 在 0x248(在最后一节的末尾)绑定了导入表地址,并且 cff 资源管理器正在覆盖这些条目(来自 kernel32.dll 的绑定导入,带有时间戳

5.1.2600.0  3B7DFE0E (18th August 2001)     926,720     Windows XP 

这就是它崩溃的原因

dumpbin /headers Winmine_test.exe | grep -i bound
             248 [      A8] RVA [size] of Bound Import Directory

原始 exe 绑定导入 modname 是@ offset 0x48 from start 即msvcrt.dll

C:\wdscr\cfftest>xxd -s 0x248 -g4 -l 0xa8 "W
0000248: 0efe7d3b 48000000 0efe7d3b 53000000
0000258: 0efe7d3b 60000000 0efe7d3b 6d000000
0000268: 0efe7d3b 77000000 0ffe7d3b 82000000
0000278: 13fe7d3b 8e000000 32fe7d3b 98000000
0000288: 00000000 00000000 6d737663 72742e64

但在 cff explorer 编辑的 exe 中绑定的导入表已损坏

xxd -s 0x248 -g 4 -l 0xa8 Winmine_test.exe
0000248: 2e746573 **74000000** 00100000 00000200  .test...........
0000258: 00100000 00d40100 00000000 00000000  ................
0000268: 00000000 200000e0 0ffe7d3b 82000000  .... .....};....
0000278: 13fe7d3b 8e000000 32fe7d3b 98000000  ..};....2.};....
0000288: 00000000 00000000 6d737663 72742e64  ........msvcrt.d
0000298: 6c6c0041 44564150 4933322e 646c6c00  ll.ADVAPI32.dll.
00002a8: 4b45524e 454c3332 2e646c6c 00474449  KERNEL32.dll.GDI
00002b8: 33322e64 6c6c0055 53455233 322e646c  32.dll.USER32.dl
00002c8: 6c005348 454c4c33 322e646c 6c005749  l.SHELL32.dll.WI
00002d8: 4e4d4d2e 646c6c00 434f4d43 544c3332  NMM.dll.COMCTL32
00002e8: 2e646c6c 00000000                    .dll....

绑定的导入表模块名称作为偏移量给出,因此第一个偏移量是 0x74

0000248: 2e746573 74000000

所以248+74 = 0x2bc

并且加载程序正在尝试加载ll.dll并且失败

6c6c00 55 53455233 322e646c 32.d**ll.**USER32.dl

你不能用用户模式调试器捕获它,因为初始化代码在调试器有机会附加之前运行

如果您在连接到内核调试器的 vm 中运行此 exe,如果您设置中断,您可以看到绑定导入失败

ntdll!LdrpHandleOneNewFormatImportDescriptor

您也可以在上下文中启用 gflag +sls(显示加载程序快照)以使加载程序快照喷出 winmine 绑定到 ll.dll,然后尝试在不存在的 dll 中执行导入

kd> r
eax=0006fa6c ebx=7ffdd000 ecx=000000b4 edx=0000415c esi=00191ec0 edi=010002bc
eip=7c91d025 esp=0006fa38 ebp=0006fa78 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
ntdll!LdrpLoadImportModule:
001b:7c91d025 8bff            mov     edi,edi


kd> kb
 # ChildEBP RetAddr  Args to Child              
00 0006fa34 7c91e4cb 00020498 010002bc 01000000 ntdll!LdrpLoadImportModule
01 0006fa78 7c91e474 7ffdd000 00020498 00191ec0 ntdll!LdrpHandleOneNewFormatImportDescriptor+0x53
02 0006fa98 7c91e5ae 7ffdd000 00020498 00191ec0 ntdll!LdrpHandleNewFormatImportDescriptors+0x20
03 0006fb14 7c921e25 00020498 00191ec0 7ffdf000 ntdll!LdrpWalkImportDescriptor+0x19e
04 0006fc94 7c92108f 0006fd30 7c900000 0006fce0 ntdll!LdrpInitializeProcess+0xe02
05 0006fd1c 7c90e437 0006fd30 7c900000 00000000 ntdll!_LdrpInitialize+0x183
06 00000000 00000000 00000000 00000000 00000000 ntdll!KiUserApcDispatcher+0x7


kd> .fnent .
Debugger function entry 039b6c60 for:
(7c91d025)   ntdll!LdrpLoadImportModule   |  (7c91d1a1)   ntdll!LdrpInitSecurityCookie
Exact matches:
    ntdll!LdrpLoadImportModule (<no parameter info>)

OffStart:  0001d025
ProcSize:  0x23a
Prologue:  0x29
Params:    0n5 (0x14 bytes)
Locals:    0n141 (0x234 bytes)
Non-FPO

kd> dd esp l6
0006fa38  7c91e4cb 00020498 010002bc 01000000
0006fa48  0006fa6c 0006fa77



kd> db 20498
00020498  43 00 3a 00 5c 00 44 00-6f 00 63 00 75 00 6d 00  C.:.\.D.o.c.u.m.
000204a8  65 00 6e 00 74 00 73 00-20 00 61 00 6e 00 64 00  e.n.t.s. .a.n.d.
000204b8  20 00 53 00 65 00 74 00-74 00 69 00 6e 00 67 00   .S.e.t.t.i.n.g.
000204c8  73 00 5c 00 61 00 64 00-6d 00 69 00 6e 00 5c 00  s.\.a.d.m.i.n.\.
000204d8  44 00 65 00 73 00 6b 00-74 00 6f 00 70 00 5c 00  D.e.s.k.t.o.p.\.
000204e8  63 00 66 00 66 00 74 00-65 00 73 00 74 00 3b 00  c.f.f.t.e.s.t.;.
000204f8  43 00 3a 00 5c 00 57 00-49 00 4e 00 44 00 4f 00  C.:.\.W.I.N.D.O.
00020508  57 00 53 00 5c 00 73 00-79 00 73 00 74 00 65 00  W.S.\.s.y.s.t.e.



kd> db 10002bc
010002bc  6c 6c 00 55 53 45 52 33-32 2e 64 6c 6c 00 53 48  ll.USER32.dll.SH
010002cc  45 4c 4c 33 32 2e 64 6c-6c 00 57 49 4e 4d 4d 2e  ELL32.dll.WINMM.
010002dc  64 6c 6c 00 43 4f 4d 43-54 4c 33 32 2e 64 6c 6c  dll.COMCTL32.dll
010002ec  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
010002fc  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0100030c  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0100031c  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
0100032c  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................


kd> db 10002bc-74
01000248  2e 74 65 73 74 00 00 00-00 10 00 00 00 00 02 00  .test...........
01000258  00 10 00 00 00 d4 01 00-00 00 00 00 00 00 00 00  ................
01000268  00 00 00 00 20 00 00 e0-0f fe 7d 3b 82 00 00 00  .... .....};....
01000278  13 fe 7d 3b 8e 00 00 00-32 fe 7d 3b 98 00 00 00  ..};....2.};....
01000288  00 00 00 00 00 00 00 00-6d 73 76 63 72 74 2e 64  ........msvcrt.d
01000298  6c 6c 00 41 44 56 41 50-49 33 32 2e 64 6c 6c 00  ll.ADVAPI32.dll.
010002a8  4b 45 52 4e 45 4c 33 32-2e 64 6c 6c 00 47 44 49  KERNEL32.dll.GDI
010002b8  33 32 2e 64 6c 6c 00 55-53 45 52 33 32 2e 64 6c  32.dll.USER32.dl