关于用VS2008来开发ACAD2009的研究

最近买了台新机器,装上了VS2008,ACAD2009,另外下载了一个ObjectARX2008.准备在家有空也可以玩玩ARX,哈哈。

     好了,回到正题,这里记录下一些关键步骤。

     这里以SDK中的ARXDBG为例。

     首先,编译刚开始肯定能过的。但必然不能被CAD加载,因为连接的库版本不对。

     在工具设置中添加mfc80u.lib和mfcs80u.lib,忽略对应90的库。这2个文件可以从装过VS2005的朋友那获得:)。相当感谢给我这个库的朋友,嘿嘿。其实如果有mfc80u.def应该也能产生出对应的lib.但有mfc80u.dll却不行,原因是它是由序号导出的,而非名字,之前的blog文也有提到。相信没有人会不想用名字,而用#XXX数字来做开发。所以库相当重要,找到这些库再继续。

     这里编译,会发现报错了。着实搞了我好久,出了三个Link Error.开始一直以为是库的问题,其实是头文件。2008中CWND类多了GetMenu和SetMenu这2个虚函数- -b,所以删除这2行,保存到SDK的INC下,同名文件(这样的好处是不影响新的VS自己的.h文件。还有一个错类似,是Cfiledialog的,多了一个默认参数。处理方法相同。这样,编译就没有问题了。

     接下来是加载。我试了半天,用Appload,失败,但拖放,可以加载成功,会有提示说和CAD不兼容。。。。但加载以后运行,未发现任何问题。

     由于之前调试过ARX的加载模块,所以今天想一试,看下到底哪里有问题。参考之前的blog设置断点。APPLOAD.arx会调用acdb17.dll::loadmoudle()方法来加载ARX。中间有很多CALL,发现最外面出问题的CALL是

631FEEA4   .  E8 E7CD0600   CALL acdb17.6326BC90

返回值不正确,跟进去。

6326BCEE   .  E8 3C09F9FF   CALL acdb17.631FC62F
6326BCF3   .  85C0          TEST EAX,EAX

返回值不对,跟进

631FC96B   .  E8 C022FEFF   CALL acdb17.631DEC30
631FC970   .  84C0          TEST AL,AL                                         ;  这里问题

返回值不对,跟进

631DEC3C   .  8B45 08       MOV EAX,DWORD PTR SS:[EBP+8]
631DEC3F   .  E8 CCFFFFFF   CALL acdb17.631DEC10 //返回不对
631DEC44      3C 08         CMP AL,8

跟进。。。

631DEC10   $  8B48 10       MOV ECX,DWORD PTR DS:[EAX+10]
631DEC13   .  85C9          TEST ECX,ECX
631DEC15   .  74 0E         JE SHORT acdb17.631DEC25
631DEC17   .  8078 05 00    CMP BYTE PTR DS:[EAX+5],0
631DEC1B   .  0F84 34CC4000 JE acdb17.635EB855
631DEC21   .  8A41 02       MOV AL,BYTE PTR DS:[ECX+2]//数值不对。。。09,应该08可以加载。数字代表撒?需要倒过来查,从ECX的出处
631DEC24   .  C3            RETN
631DEC25   >  32C0          XOR AL,AL
631DEC27   .  C3            RETN

ECX通过EAX来,然后跟到外面查EAX从EBP+8来,再跟到外面

631FC968   .  FF75 E8       PUSH DWORD PTR SS:[EBP-18]
631FC96B   .  E8 C022FEFF   CALL acdb17.631DEC30
631FC970   .  84C0          TEST AL,AL                                         ;  这里问题

数字就是从DWORD PTR SS:[EBP-18]来的,再往前找。(硬件断点)

631FC7DB   .  E8 60D2FEFF   CALL acdb17.631E9A40
631FC7E0   >  834D FC FF    OR DWORD PTR SS:[EBP-4],FFFFFFFF
631FC7E4   .  897D D8       MOV DWORD PTR SS:[EBP-28],EDI
631FC7E7   >  3BFB          CMP EDI,EBX
631FC7E9   .  0F84 13354000 JE acdb17.635FFD02
631FC7EF   .  8B47 04       MOV EAX,DWORD PTR DS:[EDI+4]
631FC7F2   >  3BC3          CMP EAX,EBX
631FC7F4   .  8945 E8       MOV DWORD PTR SS:[EBP-18],EAX//这里设置值,而EAX值从EDI来,EDI+4的内容在上面的CALL里赋值。

调试发现EAX其实只是一个指针,关键要查它对应内存里面的数值是何时赋值的。

同样硬件断点,发现EAX其实是一个new出来的内存。

631E9B1C   > /6A 34         PUSH 34
631E9B1E   . |E8 91930C00   CALL <JMP.&MSVCR80.??2@YAPAXI@Z> //new函数,乱码我也不懂。。。用VS带的undname工具。
631E9B23   . |3BC3          CMP EAX,EBX
631E9B25   . |59            POP ECX
631E9B26   . |74 19         JE SHORT acdb17.631E9B41
631E9B28   . |8BF0          MOV ESI,EAX
631E9B2A   . |8B47 10       MOV EAX,DWORD PTR DS:[EDI+10]
631E9B2D   . |885E 04       MOV BYTE PTR DS:[ESI+4],BL
631E9B30   . |8946 08       MOV DWORD PTR DS:[ESI+8],EAX
631E9B33   . |E8 98370100   CALL acdb17.631FD2D0                               ;  这里面把数据放入New出来的内存+10处

跟到里面看看

631FD341   .  8B46 18       MOV EAX,DWORD PTR DS:[ESI+18]
631FD344   .  83C0 18       ADD EAX,18
631FD347   .  8946 10       MOV DWORD PTR DS:[ESI+10],EAX//EAX为数值。出处是ESI,继续找。

后面不再列了。查看内存,直接可以发现631FD341   .  8B46 18       MOV EAX,DWORD PTR DS:[ESI+18]这行,对应的是“PE”这个字符串,结合前面观察结果,可以断定,这里是一段读取PE文件头的操作。而从PE处开始往后0x18个字节。查看文件头定义,Ollydbg也有这功能。

结果如下:

10000118    50 45 00 00>ASCII "PE"           ; PE signature (PE)
1000011C    4C01        DW 014C              ; Machine = IMAGE_FILE_MACHINE_I386
1000011E    0500        DW 0005              ;  NumberOfSections = 5
10000120    35878048    DD 48808735          ;  TimeDateStamp = 48808735
10000124    00000000    DD 00000000          ;  PointerToSymbolTable = 0
10000128    00000000    DD 00000000          ;  NumberOfSymbols = 0
1000012C    E000        DW 00E0              ;  SizeOfOptionalHeader = E0 (224.)
1000012E    0221        DW 2102              ;  Characteristics = DLL|EXECUTABLE_IMAGE|32BIT_MACHINE
10000130    0B01        DW 010B              ; MagicNumber = PE32
10000132    09          DB 09                ;  MajorLinkerVersion = 9 //就是这里,这个9就是从这里拿来的。还不明显吗,VS2008文件夹叫Microsoft Visual Studio 9.0 ,链接器的版本号。
10000133    00          DB 00                ;  MinorLinkerVersion = 0

 

综上所述,决定修改ACDB17.dll,去掉那讨厌的警告:)。回到下面

631DEC3C   .  8B45 08       MOV EAX,DWORD PTR SS:[EBP+8]
631DEC3F   .  E8 CCFFFFFF   CALL acdb17.631DEC10 //返回不对
631DEC44      3C 08         CMP AL,8      // 可以把这里改成CMP AL,9?发现CAD自己的库不行了,所以改XOR al,al,正好2个字节机器码为0x32C0

尝试加载,成功,不再报警告了。 

http://blog.sina.com.cn/s/blog_41299a970100mg04.html

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值