分解旧的.COM文件卡在48个字节之内 Endian问题?

问题描述

我玩了一个老游戏... Starflight。我认为它是在86年问世的。祝您在IBM PC上度过美好的一天。我想我会拆装一个反汇编器,看看它是如何工作的。我可以看到,在解码的过程中,可以肯定地对代码大小进行了优化……但是我最终跳到了文件外部的地址。那没有道理。

我在下面的清单中添加了评论;他们是我的“想法”。

在我假设其他文件加载之前,pd.merge_asof(df1,df2_long,on='cumul_growth_perc',by='ID',direction='nearest')int 0x3d ...因为所有段寄存器都指向相同的内存段....并且该段是代码段,所以.COM文件,每个内存引用或跳转都应保留在该文件内。是吗?

Starflt.com

int 0x0f

内存:

00000000 FA                       CLI                     ;Prevent interrupts
00000001 8CC8                     MOV AX,CS               ;Copy code segment to all segments
00000003 8ED0                     MOV SS,AX
00000005 8EC0                     MOV ES,AX
00000007 8ED8                     MOV DS,AX
00000009 BE2901                   MOV SI,word 0x0129      ;SI = 0x0129
0000000C 8B7C02                   MOV DI,word [SI+0x02]   ;DI = 0x3c15 (SI+2)
0000000F 47                       INC DI
00000010 47                       INC DI                  ;DI = 0x3c17
00000011 BB0507                   MOV BX,word 0x0705      ;BX = 0x0705
00000014 8B1F                     MOV BX,word [BX]        ;BX = 0xa924
00000016 81C30001                 ADD BX,word 0x0100      ;BX = 0xaa24
0000001A 8BE3                     MOV SP,BX               ;SP = 0xaa24 (0x0e41)
0000001C 81C38000                 ADD BX,word 0x0080      ;BX = 0xaaa4
00000020 8BEB                     MOV BP,BX               ;BP = 0xaaa4 (0x0bae)
00000022 FB                       STI                     ;Restore Interrupts
00000023 FC                       CLD                     ;Clear direction flag
00000024 AD                       LODSW                   ;AX = DS:SI = 0xfa13
00000025 8BD8                     MOV BX,AX               ;BX = 0xfa13
00000027 FF27                     JMP word [BX]           ;Past COM EOF (0xd3a7)

解决方法

您要反汇编的程序是DOS COM程序。通常,您的想法正确,但内存偏移量不正确。 DOS COM程序从内存中的空闲段(偏移量为0x100)开始加载到内存中。前0x100字节是DOS Program Segment Prefix (PSP)。您正在从偏移量0x0000拆卸,结果使用了错误的内存地址来尝试对COM程序进行解码。

不清楚您使用的是哪种反汇编程序。如果要使用ndisasm,则可以使用-o选项更改原点。如果您实际上并未使用ndisasm,则必须告诉正在使用的反汇编程序,您希望原点为0x0100而不是0x0000。对于ndisasm,您可以使用:

ndisasm -o 0x100 -b16 Starflt.com

我在网上找到了Starflight的一个副本,它似乎与您的代码相似。我使用-o 0x100得到的输出是:

00000100  FA                cli
00000101  8CC8              mov ax,cs
00000103  8ED0              mov ss,ax
00000105  8EC0              mov es,ax
00000107  8ED8              mov ds,ax
00000109  BE2901            mov si,0x129       ; si = 0x129
0000010C  8B7C02            mov di,[si+0x2]    ; di = 0x078a
0000010F  47                inc di
00000110  47                inc di             ; di = 0x078c
00000111  BB0507            mov bx,0x705
00000114  8B1F              mov bx,[bx]        ; bx = 0xd4b6
00000116  81C30001          add bx,0x100       ; bx = 0xd5b6
0000011A  8BE3              mov sp,bx          ; sp = 0xd5b6
0000011C  81C38000          add bx,0x80        ; bx = 0xd636
00000120  8BEB              mov bp,bx          ; bp = 0xd636
00000122  FB                sti
00000123  FC                cld
00000124  AD                lodsw              ; ds:si = ds:0x129 . ax = 0x0937
                                               ; si=si+2,si=0x12B 
00000125  8BD8              mov bx,ax          ; bx = 0x0937
00000127  FF27              jmp [bx]           ; jmp to cs:0x224c 
00000129  37                aaa
0000012A  098A0700          or [bp+si+0x7],cx
[snip]
00000704  F7B6D4E6          div word [bp-0x192c]
[snip]
00000937  4C                dec sp
00000938  22DB              and bl,bl
[snip]
0000224C  43                inc bx             ; Execution will continue here
0000224D  43                inc bx
0000224E  4D                dec bp
0000224F  4D                dec bp
00002250  897600            mov [bp+0x0],si
00002253  8BF3              mov si,bx
00002255  AD                lodsw
00002256  8BD8              mov bx,ax
00002258  FF27              jmp [bx]

如您所见,jmp [bx]最终从恰好在该程序的内存中的cs:0x224c开始执行。

如果您希望逐步浏览旧的16位实模式代码,我建议您使用Turbo Debugger,并使用DOSBox之类的DOS模拟器。 Starflight将在DOSBox中运行。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...