为什么我的PE文件无效?

发布于 2024-08-26 15:16:39 字数 6713 浏览 6 评论 0原文

我已经问过类似的问题,"PE 标头要求",但我对此并不满意回答。

我正在 Java SE 1.6 中构建一个汇编器/链接器。我已经阅读了大约 5 个有关 PE/COFF 标头和文件格式的不同文档/规范,但我遇到了一个问题:

Windows 说我生成的文件无效:“X 不是有效的 Win32 应用程序。 “我不知道哪里出了问题;我仔细检查了 PE 标头和 PE 可选标头中的每个条目,一切似乎都是正确的。
我有三个部分:

  • code (RVA 0x1000, File 0x400)
  • data (RVA 0x2000,文件0x600
  • 导入(RVA 0x3000,文件0x800

我的入口点值位于< code>0x1000 (code 的开头),我的图像库是 0x400000。节对齐方式为 0x1000,文件对齐方式为 0x200

查看此问题的修订版以查看整个文件。

因此:我获取了一个有效的 PE 文件(一个简单的“Hello World”消息框应用程序),并开始使用十六进制编辑器修改它(高x深)。我收到很多不同的错误消息,不是“X 不是有效的 Win32 应用程序。”:

我知道我的 code 内容不是“有效”代码,但我已经测试过:无效代码会给出应用程序崩溃错误。

如果“Hello World”PE 文件中的导入部分内容无效,则会出现错误“在 [...] 中找不到过程点”或“应用程序无法启动,因为 [..] dll 是找不到。”,或应用程序崩溃。这些错误都非常有用;他们都给了我一些线索,说明出了什么问题。

但我的 PE 文件出现错误“X 不是有效的 Win32 应用程序。”,这让我抓狂:我的 PE 文件出了什么问题?

转储箱输出:

E:\Documenten\CP Language\compiler\Win32Builder>dumpbin /ALL test.exe
Microsoft (R) COFF/PE Dumper Version 10.00.21003.01
Copyright (C) Microsoft Corporation.  All rights reserved.
Dump of file test.exe
PE signature found
File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
         14C machine (x86)
           3 number of sections
    32EB4BF5 time date stamp Sun Jan 26 13:20:05 1997
           0 file pointer to symbol table
           0 number of symbols
          E0 size of optional header
         703 characteristics
               Relocations stripped
               Executable
               32 bit word machine
               Debug information stripped
               CD - run from swapfile

OPTIONAL HEADER VALUES
         10B magic # (PE32)
        8.00 linker version
        1000 size of code
        1000 size of initialized data
           0 size of uninitialized data
        1000 entry point (00401000)
        1000 base of code
        2000 base of data
      400000 image base (00400000 to 0040088F)
        1000 section alignment
         200 file alignment
        4.00 operating system version
       13.37 image version
        4.00 subsystem version
           0 Win32 version
         890 size of image
         400 size of headers
           0 checksum
           2 subsystem (Windows GUI)
           0 DLL characteristics
       40000 size of stack reserve
       11000 size of stack commit
      100000 size of heap reserve
        1000 size of heap commit
           0 loader flags
          10 number of directories
           0 [       0] RVA [size] of Export Directory
        3000 [    1000] RVA [size] of Import Directory
           0 [       0] RVA [size] of Resource Directory
           0 [       0] RVA [size] of Exception Directory
           0 [       0] RVA [size] of Certificates Directory
           0 [       0] RVA [size] of Base Relocation Directory
           0 [       0] RVA [size] of Debug Directory
           0 [       0] RVA [size] of Architecture Directory
           0 [       0] RVA [size] of Global Pointer Directory
           0 [       0] RVA [size] of Thread Storage Directory
           0 [       0] RVA [size] of Load Configuration Directory
           0 [       0] RVA [size] of Bound Import Directory
           0 [       0] RVA [size] of Import Address Table Directory
           0 [       0] RVA [size] of Delay Import Directory
           0 [       0] RVA [size] of COM Descriptor Directory
           0 [       0] RVA [size] of Reserved Directory

SECTION HEADER #1
   .code name
    1000 virtual size
    1000 virtual address (00401000 to 00401FFF)
      23 size of raw data
     400 file pointer to raw data (00000400 to 00000422)
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
60000020 flags
         Code
         Execute Read    
RAW DATA #1
  00401000: 68 00 00 00 00 68 0D 20 40 00 68 00 20 40 00 68  h....h. @.h. @.h
  00401010: 00 00 00 00 E8 64 30 40 00 68 00 00 00 00 E8 6C  ....è[email protected]....èl
  00401020: 30 40 00                                         0@.

SECTION HEADER #2
   .data name
    1000 virtual size
    2000 virtual address (00402000 to 00402FFF)
      23 size of raw data
     600 file pointer to raw data (00000600 to 00000622)
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
C0000040 flags
         Initialized Data
         Read Write
RAW DATA #2
  00402000: 48 65 6C 6C 6F 20 57 6F 72 6C 64 21 00 48 65 6C  Hello World!.Hel
  00402010: 6C 6F 20 53 74 61 63 6B 20 4F 76 65 72 66 6C 6F  lo Stack Overflo
  00402020: 77 21 00                                         w!.

SECTION HEADER #3
 .import name
    1000 virtual size
    3000 virtual address (00403000 to 00403FFF)
      90 size of raw data
     800 file pointer to raw data (00000800 to 0000088F)
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
50000040 flags
         Initialized Data
         Shared
         Read Only
RAW DATA #3
  00403000: 54 30 00 00 00 00 00 00 00 00 00 00 3C 30 00 00  T0..........<0..
  00403010: 64 30 00 00 5C 30 00 00 00 00 00 00 00 00 00 00  d0..\0..........
  00403020: 47 30 00 00 6C 30 00 00 00 00 00 00 00 00 00 00  G0..l0..........
  00403030: 00 00 00 00 00 00 00 00 00 00 00 00 75 73 65 72  ............user
  00403040: 33 32 2E 64 6C 6C 00 6B 65 72 6E 65 6C 33 32 2E  32.dll.kernel32.
  00403050: 64 6C 6C 00 74 30 00 00 00 00 00 00 82 30 00 00  dll.t0.......0..
  00403060: 00 00 00 00 74 30 00 00 00 00 00 00 82 30 00 00  ....t0.......0..
  00403070: 00 00 00 00 00 00 4D 65 73 73 61 67 65 42 6F 78  ......MessageBox
  00403080: 41 00 00 00 45 78 69 74 50 72 6F 63 65 73 73 00  A...ExitProcess.

  Section contains the following imports:

user32.dll
            403064 Import Address Table
            403054 Import Name Table
                 0 time date stamp
                 0 Index of first forwarder reference

                0 MessageBoxA

kernel32.dll
            40306C Import Address Table
            40305C Import Name Table
                 0 time date stamp
                 0 Index of first forwarder reference

                0 ExitProcess

Summary
    1000 .code
    1000 .data
    1000 .import

I already asked a similar question, "PE Header requirements", but I'm not really satisfied with it's answer.

I am building an assembler/linker, in Java SE 1.6. I have read about 5 different documentations/specifications about the PE/COFF header and file format, but I'm stuck at a problem:

My generated file is not valid, says Windows: "X is not a valid Win32 application." I'm clueless of what can be wrong; I have double-checked every entry in the PE Header and PE Optional Header, and all seems to be right.
I've got three sections:

  • code (RVA 0x1000, File 0x400)
  • data (RVA 0x2000, File 0x600)
  • import (RVA 0x3000, File 0x800)

My entrypoint value is at 0x1000 (the beginning of code) and my imagebase is 0x400000. Section alignment is 0x1000 and file alignment is 0x200.

See the revisions of this question to see the whole file.

So: I grabbed a valid PE file (a simple "Hello World" message box application), and started to modify it, with a hex-editor (HxD). I got a lot of different error messages, not the "X is not a valid Win32 application.":

I'm aware that my code content is not "valid" code, but I've tested it out: invalid code gives an Application Crash error.

If the import-section content is invalid in the "Hello World" PE file, it gives me the error "Procedure point cannot be found in [...]", or "Application has failed to start because [..] dll is not found.", or an Application Crash. These errors are all very useful; they all give me some clue what was wrong.

But my PE file, with the error "X is not a valid Win32 application.", drives me insane: What is wrong with my PE file?

Dumpbin output:

E:\Documenten\CP Language\compiler\Win32Builder>dumpbin /ALL test.exe
Microsoft (R) COFF/PE Dumper Version 10.00.21003.01
Copyright (C) Microsoft Corporation.  All rights reserved.
Dump of file test.exe
PE signature found
File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
         14C machine (x86)
           3 number of sections
    32EB4BF5 time date stamp Sun Jan 26 13:20:05 1997
           0 file pointer to symbol table
           0 number of symbols
          E0 size of optional header
         703 characteristics
               Relocations stripped
               Executable
               32 bit word machine
               Debug information stripped
               CD - run from swapfile

OPTIONAL HEADER VALUES
         10B magic # (PE32)
        8.00 linker version
        1000 size of code
        1000 size of initialized data
           0 size of uninitialized data
        1000 entry point (00401000)
        1000 base of code
        2000 base of data
      400000 image base (00400000 to 0040088F)
        1000 section alignment
         200 file alignment
        4.00 operating system version
       13.37 image version
        4.00 subsystem version
           0 Win32 version
         890 size of image
         400 size of headers
           0 checksum
           2 subsystem (Windows GUI)
           0 DLL characteristics
       40000 size of stack reserve
       11000 size of stack commit
      100000 size of heap reserve
        1000 size of heap commit
           0 loader flags
          10 number of directories
           0 [       0] RVA [size] of Export Directory
        3000 [    1000] RVA [size] of Import Directory
           0 [       0] RVA [size] of Resource Directory
           0 [       0] RVA [size] of Exception Directory
           0 [       0] RVA [size] of Certificates Directory
           0 [       0] RVA [size] of Base Relocation Directory
           0 [       0] RVA [size] of Debug Directory
           0 [       0] RVA [size] of Architecture Directory
           0 [       0] RVA [size] of Global Pointer Directory
           0 [       0] RVA [size] of Thread Storage Directory
           0 [       0] RVA [size] of Load Configuration Directory
           0 [       0] RVA [size] of Bound Import Directory
           0 [       0] RVA [size] of Import Address Table Directory
           0 [       0] RVA [size] of Delay Import Directory
           0 [       0] RVA [size] of COM Descriptor Directory
           0 [       0] RVA [size] of Reserved Directory

SECTION HEADER #1
   .code name
    1000 virtual size
    1000 virtual address (00401000 to 00401FFF)
      23 size of raw data
     400 file pointer to raw data (00000400 to 00000422)
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
60000020 flags
         Code
         Execute Read    
RAW DATA #1
  00401000: 68 00 00 00 00 68 0D 20 40 00 68 00 20 40 00 68  h....h. @.h. @.h
  00401010: 00 00 00 00 E8 64 30 40 00 68 00 00 00 00 E8 6C  ....è[email protected]....èl
  00401020: 30 40 00                                         0@.

SECTION HEADER #2
   .data name
    1000 virtual size
    2000 virtual address (00402000 to 00402FFF)
      23 size of raw data
     600 file pointer to raw data (00000600 to 00000622)
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
C0000040 flags
         Initialized Data
         Read Write
RAW DATA #2
  00402000: 48 65 6C 6C 6F 20 57 6F 72 6C 64 21 00 48 65 6C  Hello World!.Hel
  00402010: 6C 6F 20 53 74 61 63 6B 20 4F 76 65 72 66 6C 6F  lo Stack Overflo
  00402020: 77 21 00                                         w!.

SECTION HEADER #3
 .import name
    1000 virtual size
    3000 virtual address (00403000 to 00403FFF)
      90 size of raw data
     800 file pointer to raw data (00000800 to 0000088F)
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
50000040 flags
         Initialized Data
         Shared
         Read Only
RAW DATA #3
  00403000: 54 30 00 00 00 00 00 00 00 00 00 00 3C 30 00 00  T0..........<0..
  00403010: 64 30 00 00 5C 30 00 00 00 00 00 00 00 00 00 00  d0..\0..........
  00403020: 47 30 00 00 6C 30 00 00 00 00 00 00 00 00 00 00  G0..l0..........
  00403030: 00 00 00 00 00 00 00 00 00 00 00 00 75 73 65 72  ............user
  00403040: 33 32 2E 64 6C 6C 00 6B 65 72 6E 65 6C 33 32 2E  32.dll.kernel32.
  00403050: 64 6C 6C 00 74 30 00 00 00 00 00 00 82 30 00 00  dll.t0.......0..
  00403060: 00 00 00 00 74 30 00 00 00 00 00 00 82 30 00 00  ....t0.......0..
  00403070: 00 00 00 00 00 00 4D 65 73 73 61 67 65 42 6F 78  ......MessageBox
  00403080: 41 00 00 00 45 78 69 74 50 72 6F 63 65 73 73 00  A...ExitProcess.

  Section contains the following imports:

user32.dll
            403064 Import Address Table
            403054 Import Name Table
                 0 time date stamp
                 0 Index of first forwarder reference

                0 MessageBoxA

kernel32.dll
            40306C Import Address Table
            40305C Import Name Table
                 0 time date stamp
                 0 Index of first forwarder reference

                0 ExitProcess

Summary
    1000 .code
    1000 .data
    1000 .import

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

孤独岁月 2024-09-02 15:16:39

你肯定是从错误的角度解决这个问题的。破解十六进制永远不会得到你想要的东西,PE 文件结构太复杂了。你需要两件事。

  • Matt Pietrek 的开创性文章是理解其结构的必读书。在理解至少 75% 之前不要开始编写代码。
  • 您将需要 Windows SDK。 include/winnt.h 文件包含 PE 格式中使用的结构的声明。它从 _IMAGE_DOS_HEADER 开始,即文件的第一个块。

编写代码以根据其声明创建结构,这是最终获得有效可执行文件的唯一方法。

PS:您的十六进制转储会挂起任何试图查看您的问题的人的浏览器。

You are definitely tackling this problem from the wrong end. Hacking the hex isn't ever going to get you what you want, the PE file structure is too sophisticated. You'll need two things.

  • Matt Pietrek's seminal article is essential reading to understand the structure. Don't get started on code until you understand at least 75% of it.
  • You'll need the Windows SDK. The include/winnt.h file contains the declarations of the structures used in the PE format. It starts at _IMAGE_DOS_HEADER, the first chunk of the file.

Write the code to create the structures from their declarations, that's the only way to end up with a valid executable file.

PS: your hex dumps hang up the browsers of anybody that tries to look at your question.

丑疤怪 2024-09-02 15:16:39

快速谷歌显示:

http://rcecafe.net/?p=26。这里没有人会为你卑躬屈膝地阅读你的字节,你能期望的最好的就是指向工具的指针。

A quick google revealed:

http://rcecafe.net/?p=26. No one here is going to grovel through your bytes for you, the best you can expect is pointers to tools.

望她远 2024-09-02 15:16:39

根据dumpbin 890,图像的大小应该是内存中图像的大小,即最新部分的RVA + 该部分的四舍五入大小(例如0x5000代码> 在这种情况下)。

有用。感谢您的 anserws,特别是对 dumpbin 的提示!

The Size Of Image is, according to dumpbin 890, while it should be the size of image in the memory, i.e. the latest section's RVA + that section's rounded-up size (e.g. 0x5000 in this case).

It works. Thanks for anserws, especially the hint to dumpbin!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文