这几天研读了你的内容,解开了我对16位程序的一些疑惑,另外还有些需要向likelove前辈请教的地方。
静态分析只用ida就好,版本不限。在winxp下,低版本的优势在于可选繁体中文字库。不过也无所谓。在新的操作系统下,我通常用total commander文件管理器F3功能来浏览文件内容,切换文本模式、16进制模式很方便,并借助互联网翻译来实现对繁体中文和日文与简中的对应。
动态调试推荐vwware环境,dos占用空间也不大,动态调试器可用softice,通过静态分析提供的网址来设置动态断点,实现调试的目的。
total commander我试了一下,F3的时候能看到16进制编码,修改要调到F4模式下,又看不到16进制编码,感觉不如直接用UE来修改。我现在使用的是CE修改器来查看dosbox中16位程序内存,然后用CE的读写断点来调试,你能提供几张softice的截图看看是怎么设置断点以及单步调试,我比较一下哪种更好。
第二种办法是动态内存修改,不直接改文件。
修改内存需要对文件作扩容,有两种改法:
一是单纯在文件头中改堆栈设置参数,将堆栈区向内存高地址去推,这样你得到原堆栈区与新堆栈区的内存是原始程序未用到的,是安全的。比如将堆栈区从3dc7:0000上推为5dc7:0000,这样3dc7:0000至5dc7:0000的内存空间都是可用的,用于存放代的超过了堆栈区的空间可能会被其他程序、分配的内存使用,修改、使用不安全;
这个扩容版的改法只用将文件头的那里改掉吗?然后内存结构就变成了代码段+数据堆栈段+空置段+外部数据段,就可以在空置段上加代码和数据了对吗?本来以为是在seg006和dseg中间重新加一个段,不过我看CE内存中的DS和SS的地址都没变,以为没啥用。
二是在一改法的基础上在exe文件尾同步增加全0内容,确保初始的新增内存内容都为0,或者放置自己修改的代码。
这个方法有用吗,你看我下面的代码分析,新增的内容不会被堆区覆盖吗?
seg000:BCE6 public start
seg000:BCE6 start proc far
seg000:BCE6 B4 30 mov ah, 30h
seg000:BCE8 CD 21 int 21h ; DOS - GET DOS VERSION
seg000:BCE8 ; Return: AL = major version number (00h for DOS 1.x)
seg000:BCEA 3C 02 cmp al, 2
seg000:BCEC 73 05 jnb short loc_1BCF3
seg000:BCEE 33 C0 xor ax, ax ; DOS VER 太小运行不了
seg000:BCF0 06 push es
seg000:BCF1 50 push ax
seg000:BCF2 CB retf
seg000:BCF3 loc_1BCF3: ; CODE XREF: start+6↑j
seg000:BCF3 BF 7D 40 mov di, seg dseg ;用不用修改这个数值?
...
seg000:BD06 8E D7 mov ss, di
...
seg000:BD70 16 push ss
seg000:BD71 07 pop es
seg000:BD72 assume es:dseg
seg000:BD72 FC cld
seg000:BD73 BF 26 51 mov di, 5126h
seg000:BD76 B9 A0 D4 mov cx, 0D4A0h
seg000:BD79 2B CF sub cx, di
seg000:BD7B 33 C0 xor ax, ax
seg000:BD7D F3 AA rep stosb ; 堆区(SS:5126 - SS:D49F)初始化为0
...
seg000:BD9A 16 push ss
seg000:BD9B 1F pop ds ; 堆和栈处于为同一段
seg000:BD9C FF 36 54 47 push word_44F24
seg000:BDA0 FF 36 52 47 push argv ; argv
seg000:BDA4 FF 36 50 47 push argc ; argc
seg000:BDA8 9A CC 9F F6 1C call _main
dos程序并没有api可用,动画是通过对显存的读写和IO接口来直接写屏实现的。需要对照VGA显示器的调用约定来实现,操作较复杂。
关于你的dosbox trainer工具我有个Issues,offset=的后面也增加写成[sg01]XXXX这种形式的功能,不然换算太麻烦了。
我看你的ida分析文件有大量VGA和EGA开头命名的函数,想问一下你是有这些函数的源代码与反汇编代码进行对照的吗,或者说你是怎么命名的?
另外,英杰传用到了自修改技术(smc),第一次看到时简直震惊了。英杰传中有些参数是通过直接修改相应函数里面相应指令的内存代码实现的。
这种应该算过时的技术,说简单点就是代码是无保护的,代码可以自我修改,这部分代码好像只在seg000出现,怀疑是由8位程序的一些原有代码改写过来的,因为其中有大量重复代码,却没有用上rep, loop这样的循环结构。
实际上我们现在的一些32位64位程序,一开始也会执行一部分16位程序代码,可能就相当于在16位环境下运行的32位64位程序。