内存中的.text在执行期间被覆盖

时间:2012-08-16 16:12:44

标签: assembly process linux-kernel gdb portable-executable

我一直在为Linux开发一个简单的PE流程加载器。我想我已经掌握了基础知识;我使用的大部分代码来自binfmt_elf.cbinfmt_aout.c。我的测试可执行文件尽可能简单(FASM格式):

format PE GUI 4.0
entry main

section '.text' code readable executable
main:
    mov eax, 4
    add eax, 5
    ret

这个程序(math1)是32位编译的,我运行的VM(Xubuntu 12.04)也是32位。我将加载器编译为内核模块,并使用insmod进行安装。加载器似乎工作到目前为止,我已经检查了每个可能步骤的错误代码。所有这一切都是mmap起始地址0x401000的代码部分,并使用该地址调用start_thread()。如果我在命令行输入类似./math1.exe的内容,我的加载器确实被调用了。所以,如果一切按计划进行,我每次都应得到返回值9。但是,不是每次都执行math1段错误,所以我在gdb中打开它以查看发生了什么。

在执行之前,一切看起来都很正常。如果我在起始地址转储,我会看到我应该知道的(我可以确认这是上述程序的机器代码):

(gdb) x/9xb 0x401000
0x401000:   0xb8    0x04    0x00    0x00    0x00    0x83    0xc0    0x05
0x401008:   0xc3
(gdb) run
Starting program: /media/sf_Sandbox/math1.exe 

Program received signal SIGSEGV, Segmentation fault.
0x00401002 in ?? ()

在segfault之后,转储到同一个地址,内存已完全改变,并且从寄存器转储中看起来似乎没有执行第一条指令:

(gdb) x/9xb 0x401000
0x401000:   0x4d    0x5a    0x80    0x00    0x01    0x00    0x00    0x00
0x401008:   0x04
(gdb) info all-registers
eax            0x0  0
ecx            0x81394e8    135501032
edx            0x64656d2f   1684368687
ebx            0x8139548    135501128
esp            0xbfffe5a0   0xbfffe5a0
ebp            0xffffffff   0xffffffff
esi            0x81394e8    135501032
edi            0x2f7ff4 3112948
eip            0x401002 0x401002
eflags         0x210296 [ PF AF SF IF RF ID ]
cs             0x73 115
ss             0x7b 123
ds             0x7b 123
es             0x7b 123
fs             0x0  0
gs             0x0  0
...more registers...

我想知道会发生什么样的事情,以及我可以做些什么来解决它。我怀疑用于设置堆栈帧的代码可能有点......关闭,但我不知道如何判断这是否是导致这种情况的原因。我知道这是一个非常具体的问题,但我希望有人可以给我一些建议。

1 个答案:

答案 0 :(得分:0)

错误是由我的页面对齐错误引起的,而神秘的十六进制转储内容实际上是有问题的PE文件的MS-DOS头。我使用kernel_readcopy_to_user代替do_mmap修复了此问题,以避免在非页面对齐的部分出现故障。