明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 3833|回复: 16

[经验] fas格式研究(三) 内存中的fas和lsp

[复制链接]
发表于 2018-12-6 11:15:19 | 显示全部楼层 |阅读模式
本帖最后由 baitang36 于 2021-8-9 13:16 编辑

根据新的研究,纠正了原来的一些错误理解。2021-8-9

写一个小程序:
(defun C:TTT() (SETQ A 8)(PRINC "TTT"))
(defun C:AAA() (PRINC "AA"))
(defun C:ccc() (PRINC "c"))
编译后解码:
Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F
00000000   0D 0A 20 46 41 53 34 2D  46 49 4C 45 20 3B 20 44      FAS4-FILE ; D
00000010   6F 20 6E 6F 74 20 63 68  61 6E 67 65 20 69 74 21   o not change it!
00000020   0D 0A 34 37 0D 0A 36 20  24 14 00 00 00 00 32 08     47  6 $     2
00000030   06 05 00 09 04 00 35 01  03 00 03 16 14 00 00 00         5         
00000040   00 09 02 00 35 01 03 00  03 16 14 00 00 00 00 09       5           
00000050   01 00 35 01 03 00 03 16  24 0D 0A 32 34 36 20 39     5     $  246 9
00000060   20 24 14 01 01 01 00 32  00 32 51 2A 39 01 00 5B    $     2 2Q*9  [
00000070   43 3A 43 43 43 00 43 3A  41 41 41 00 00 56 76 6C   C:CCC C:AAA  Vvl
00000080   2D 41 43 41 44 2D 64 65  66 75 6E 00 00 5B 43 3A   -ACAD-defun  [C:
00000090   54 54 54 00 00 01 01 43  00 00 06 00 0A 32 21 32   TTT    C     2!2
000000A0   2F 2A 32 13 32 21 2A 32  00 32 13 2A 39 03 00 55   /*2 2!*2 2 *9  U
000000B0   02 00 01 00 63 02 00 41  41 5B 50 52 49 4E 43 00       c  AA[PRINC
000000C0   00 55 01 00 03 00 54 54  54 5B 41 00 00 5C 00 00    U    TTT[A  \  
000000D0   43 00 00 06 00 0A 5C 00  00 32 21 5B 43 3A 43 43   C     \  2![C:CC
000000E0   43 00 00 3A 5C 00 00 32  13 5B 43 3A 41 41 41 00   C  :\  2 [C:AAA
000000F0   00 3A 5C 00 00 32 00 5B  43 3A 54 54 54 00 00 3A    :\  2 [C:TTT  :
00000100   01 43 06 00 03 00 1C 14  01 00 00 00 09 05 00 0A    C              
00000110   57 00 00 00 00 09 08 00  06 04 00 09 04 00 35 01   W             5
00000120   03 00 01 0A 09 04 00 0A  57 00 00 00 00 09 07 00           W      
00000130   06 02 00 09 02 00 35 01  03 00 01 0A 09 02 00 0A         5         
00000140   57 00 00 00 00 09 06 00  06 01 00 09 01 00 35 01   W             5
00000150   03 00 01 0A 09 01 00 16  15 00 0A 58 3D EF 83 0A              X=飪
00000160   3B 66 61 73 34 20 63 72  75 6E 63 68 0A 3B 24 3B   ;fas4 crunch ;$;
00000170   41 31 32 2F 36 2F 31 38                            A12/6/18
可以看出这三个自定义函数的代码如下:
14 00 00 00 00 32 08 06 05 00 09 04 00 35 01 03 00 03 16
14 00 00 00 00 09 02 00 35 01 03 00 03 16
14 00 00 00 00 09 01 00 35 01 03 00 03 16


在cad2008下加载,然后用感叹号获取函数的编号
命令: !c:ttt
#<SUBR @165644ec C:TTT>
命令: !c:aaa
#<SUBR @165644d8 C:AAA>
命令: !c:ccc
#<SUBR @165644c4 C:CCC>
用od查看从165644c4开始的内存,很明显是个表:
165644C4  04 62 C1 0F 00 00 00 00 20 35 55 16 F8 D7 EA 10  b?.... 5U?
165644D4  21 00 00 00 04 62 C1 0F 00 00 00 00 68 12 83 15  !...b?....h?
165644E4  F8 D7 EA 10 13 00 00 00 04 62 C1 0F 00 00 00 00  ?...b?....
165644F4  80 12 83 15 F8 D7 EA 10 00 00 00 00   
可以看出每个函数占用20个字节,对齐了看
c:ccc函数是:
165644C4:  04 62 C1 0F 00 00 00 00 20 35 55 16 F8 D7 EA 10 21 00 00 00
c:aaa函数:                                    
165644D8:  04 62 C1 0F 00 00 00 00 68 12 83 15 F8 D7 EA 10 13 00 00 00
c:ttt函数:                                    
165644EC:  04 62 C1 0F 00 00 00 00 80 12 83 15 F8 D7 EA 10 00 00 00 00
                                     ....
第一个字04 62 C1 0F是相同的,能找到好多个,远多于我们的函数个数3。经研究,它是个记号,叫 xsub::mark,表示是函数,和单个fas无关。用户自定义的函数就是xsubr。
第二个字 00 00 00 00都是0,不研究
第三个字20 35 55 16 各不相同,存放的是函数名。
第四个字F8 D7 EA 10只有三个是相同的,本程序定义了三个函数,这个字应该是和fas相关的,叫module。一个fas加载后会产生两个module。
第五个字21 00 00 00函数代码的偏移值,是函数代码所存放的位置,调用函数时会访问到这个地址。
用od看一下第四个字指向的内存地址,发现还是个表:
10EAD7F8:  F0 43 C1 0F 00 00 00 00 00 A4 62 16 47 00 00 00 06 00 00 00
第一个字F0 43 C1 0F是个记号module::mark,表示这块数据是个module。
第二个字是0,也不管
第三个字是00 A4 62 16有点意思,是module的开始地址
第四个字是47 00 00 00,表示的是module的大小
第五个字是06 00 00 00它是本函数前面的符号个数,乘以四再加上module开始地址就是本函数的开始地址。
0x1662A400+6*4=0x1662A418,就是函数开始地址。
一个文件中有多个函数时,还要加上第一个表中的第五个字才是函数开始地址。
用od看module的开始地址指向的内存:
1662A400  C8 C9 5A 16 98 DF 55 16 A8 DF 55 16 58 79 7F 15  壬Z樳UㄟUXy
1662A410  B8 DF 55 16 98 12 83 15
14 00 00 00 00 32 08 06  高U??....2
1662A420  05 00 09 04 00 35 01 03 00 03 16 14 00 00 00 00  ...5.....
1662A430  09 02 00 35 01 03 00 03 16 14 00 00 00 00 09 01  ..5......
1662A440  00 35 01 03 00 03 16
00 00 00 00 00 00 00 00 00  .5..........
1662A450  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
1662A460  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
1662A470  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
1662A480  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
1662A490  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
1662A4A0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
1662A4B0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
1662A4C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
1662A4D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
1662A4E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
1662A4F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
1662A500  68 C9 5A 16 20 35 55 16 68 12 83 15 E8 4F E4 10  h蒢 5Uh?鐿?
1662A510  80 12 83 15 00 00 00 00 C4 44 56 16 D8 44 56 16  
1662A520  EC 44 56 16
14 01 01 01 00 32 00 32 51 2A 39 01  霥V.2.2Q*9
1662A530  00 5B 43 3A 43 43 43 00 43 3A 41 41 41 00 00 56  .[C:CCC.C:AAA..V
1662A540  76 6C 2D 41 43 41 44 2D 64 65 66 75 6E 00 00 5B  vl-ACAD-defun..[
1662A550  43 3A 54 54 54 00 00 01 01 43 00 00 06 00 0A 32  C:TTT..C....2
1662A560  21 32 2F 2A 32 13 32 21 2A 32 00 32 13 2A 39 03  !2/*22!*2.2*9
1662A570  00 55 02 00 01 00 63 02 00 41 41 5B 50 52 49 4E  .U..c.AA[PRIN
1662A580  43 00 00 55 01 00 03 00 54 54 54 5B 41 00 00 5C  C..U..TTT[A..\
1662A590  00 00 43 00 00 06 00 0A 5C 00 00 32 21 5B 43 3A  ..C....\..2![C:
1662A5A0  43 43 43 00 00 3A 5C 00 00 32 13 5B 43 3A 41 41  CCC..:\..2[C:AA
1662A5B0  41 00 00 3A 5C 00 00 32 00 5B 43 3A 54 54 54 00  A..:\..2.[C:TTT.
1662A5C0  00 3A 01 43 06 00 03 00 1C 14 01 00 00 00 09 05  .:C......
1662A5D0  00 0A 57 00 00 00 00 09 08 00 06 04 00 09 04 00  ..W.........
1662A5E0  35 01 03 00 01 0A 09 04 00 0A 57 00 00 00 00 09  5.....W.....
1662A5F0  07 00 06 02 00 09 02 00 35 01 03 00 01 0A 09 02  ....5...
1662A600  00 0A 57 00 00 00 00 09 06 00 06 01 00 09 01 00  ..W.........
1662A610  35 01 03 00 01 0A 09 01 00 16                    5....

在这里看到我们熟悉的东西,蓝色的部分是函数部分的符号。

再来看看lsp的情况:
建立一个小程序ttt.lsp
内容如下:
(defun C:TTT() (SETQ A 8)(PRINC "TTT")) (defun C:AAA() (PRINC "AA")) (defun C:ccc() (PRINC "c"))
用(load "ttt.lsp")加载
执行命令 !c:ttt
显示#<SUBR @10bebc44 C:TTT>
查看0x10bebc44这个内存地址,内容如下:
10BEBC44:04 62 93 10    00 00 00 00     50 8B BF 0F    44 D2 AA 10    00 00 00 00  
查看这张表的第四项是0x10AAD244
10AAD244:F0 43 93 10    00 00 00 00     00 85 B2 10    2A 00 00 00    05 00 00 00                                 
查看这张表的第三项是0x10B28500,第五项是05
10B28500  18 EE C1 0F 00 00 00 00 68 8B BF 0F 68 21 C0 0F  
10B28510  F8 28 AF 10 17 01 00 32 08 0B 06 02 00 0A 09 03  
10B28520  00 09 04 00 34 01 03 21 00
                     
C:TTT函数的开始地址是:
0x10B28500+5*4=0x10B28514
查看0x10B28514这个地址的内容:
10B28514:17 01 00 32 08 0B 06 02 00 0A 09 03   00 09 04 00 34 01 03 21  
32 08 0B 06 02 00 0A就是(SETQ A 8)
09 03 00 09 04 00 34 01 03 21 00就是(PRINC "TTT")
再试验一个,!c:aaa
#<SUBR @10bebc6c C:AAA>
第一张表
10BEBC6C:04 62 93 10  00 00 00 00  B0 8B BF 0F 6C D2 AA 10  00 00 00 00                                    
第二张表
10AAD26C:  F0 43 93 10  00 00 00 00  00 FA AD 10   1F 00 00 00   04 00 00 00  
函数开始地址:                                    
0x10adfa00+4*4=0x10adfa10
10ADFA00  68 D2 C1 0F  00 00 00 00  A8 21 C0 0F  F8 28 AF 10  
10ADFA10  17 01 00 09 02 00 09 03 00 34 01 03 21 00        
看来函数的代码都是17开头的,09 02 00 09 03 00 34 01 03 21 00是(PRINC "AA")


研究了几天内存,得出如下结论:
1.lsp程序在加载以后是按函数分散的内存中的,同一个lsp文件的函数并不挨在一起,不存在完整的lsp文件
2.fas文件所有的函数都挨在一起的。
3.lsp在内存中存放的不是源码,是经过编译的代码,这种代码用了更多的指令。





评分

参与人数 1明经币 +2 收起 理由
yxp + 2 很有价值的研究

查看全部评分

"觉得好,就打赏"
还没有人打赏,支持一下
 楼主| 发表于 2019-1-14 07:52:24 | 显示全部楼层
本帖最后由 baitang36 于 2019-1-14 08:01 编辑

(defun C:EP-SZBZ()
(XYP-DCL-GETTILE '("k1" "k2" ) )
(cond ( (= K1 "0" )
(MODE_TILE "qz" 0 )
(MODE_TILE "xh" 0 )
)
命令: (LOAD "111.fas") C:EP-SZBZ
命令: !c:ep-szbz
#<SUBR @1907bce4 C:EP-SZBZ>

1907BCE4  04 62 47 10 00 00 00 00 50 8B 76 1A 80 D2 F3 18
1907BCF4  00 00 00 00   

18F3D280  F0 43 47 10 00 00 00 00 00 06 F7 18 3C 05 00 00
18F3D290 59 00 00 00

0x18f70600+0x59*4=0x18f70764
18F70764  14 00 00 00 00 09 56 00 51 01 55 00 01 00 0A 03  .....V.QU...
18F70774  54 00 35 01 53 00 03 67 1A 00 00 00 09 52 00 09  T.5S.g....R..
18F70784  51 00 09 50 00 32 01 32 06 32 05 35 06 4F 00 03  Q..P.2225O.
18F70794  0A 57 00 00 00 00 35 00 4E 00 03 0A 57 E0 02 00  .W....5.N..W?.
18F707A4  00 14 01 00 00 00 09 4D 00 51 01 55 00 01 00 0A  .....M.QU...
18F707B4  03 4C 00 09 4B 00 35 02 4A 00 03 67 F9 00 00 00  L..K.5J.g?..
18F707C4  01 09 49 00 35 01 48 00 03 35 01 47 00 03 0B 06  .I.5H.5G. 
18F707D4  46 00 6A 27 00 00 00 03 46 00 09 45 00 35 02 44  F.j'...F..E.5D
18F707E4  00 03 6A 17 00 00 00 32 46 03 46 00 35 02 43 00  .j...2FF.5C.
18F707F4  03 32 01 35 02 4A 00 03 6A 01 00 00 00 02 67 B1  25J.j...g?
18F70804  00 00 00 0A 35 00 42 00 03 0A 03 46 00 32 01 03  ....5.B..F.2
18F70814  41 00 35 03 40 00 03 06 3F 00 32 00 06 3E 00 09  A.5@.?.2.>..
18F70824  3D 00 32 03 35 02 3C 00 03 0A 03 3B 00 09 4B 00  =.25<..;..K.
18F70834  35 02 4A 00 03 67 11 00 00 00 03 46 00 03 3A 00  5J.g...F.:.
18F70844  35 02 39 00 03 0A 57 00 00 00 00 35 00 38 00 03  59..W....5.8.
18F70854  0A 03 37 00 09 4B 00 35 02 4A 00 03 6A 12 00 00  .7..K.5J.j..
18F70864  00 09 36 00 35 01 35 00 03 0B 06 34 00 6A 01 00  ..6.55. 4.j.
18F70874  00 00 02 67 36 00 00 00 09 33 00 03 3F 00 35 02  ..g6....3.?.5
18F70884  32 00 03 06 31 00 09 30 00 03 31 00 35 02 2F 00  2.1..0.1.5/.
18F70894  03 06 31 00 03 34 00 03 31 00 03 3A 00 03 3A 00  1.4.1.:.:.
18F708A4  35 04 2E 00 03 0B 06 2D 00 57 01 00 00 00 01 57  5.. -.W...W
18F708B4  0D FF FF FF


Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F
00000000   0D 0A 20 46 41 53 34 2D  46 49 4C 45 20 3B 20 44      FAS4-FILE ; D
00000010   6F 20 6E 6F 74 20 63 68  61 6E 67 65 20 69 74 21   o not change it!
00000020   0D 0A 39 38 34 0D 0A 38  39 20 24 14 00 00 00 00     984  89 $     
00000030   09 56 00 51 01 55 00 01  00 0A 03 54 00 35 01 53    V Q U     T 5 S
00000040   00 03 67 1A 00 00 00 09  52 00 09 51 00 09 50 00     g     R  Q  P
00000050   32 01 32 06 32 05 35 06  4F 00 03 0A 57 00 00 00   2 2 2 5 O   W   
00000060   00 35 00 4E 00 03 0A 57  E0 02 00 00 14 01 00 00    5 N   W?      
00000070   00 09 4D 00 51 01 55 00  01 00 0A 03 4C 00 09 4B     M Q U     L  K
00000080   00 35 02 4A 00 03 67 F9  00 00 00 01 09 49 00 35    5 J  g?    I 5
00000090   01 48 00 03 35 01 47 00  03 0B 06 46 00 6A 27 00    H  5 G    F j'
000000A0   00 00 03 46 00 09 45 00  35 02 44 00 03 6A 17 00      F  E 5 D  j  
000000B0   00 00 32 46 03 46 00 35  02 43 00 03 32 01 35 02     2F F 5 C  2 5
000000C0   4A 00 03 6A 01 00 00 00  02 67 B1 00 00 00 0A 35   J  j     g?   5
000000D0   00 42 00 03 0A 03 46 00  32 01 03 41 00 35 03 40    B    F 2  A 5 @
000000E0   00 03 06 3F 00 32 00 06  3E 00 09 3D 00 32 03 35      ? 2  >  = 2 5
000000F0   02 3C 00 03 0A 03 3B 00  09 4B 00 35 02 4A 00 03    <    ;  K 5 J  
00000100   67 11 00 00 00 03 46 00  03 3A 00 35 02 39 00 03   g     F  : 5 9  
00000110   0A 57 00 00 00 00 35 00  38 00 03 0A 03 37 00 09    W    5 8    7  
00000120   4B 00 35 02 4A 00 03 6A  12 00 00 00 09 36 00 35   K 5 J  j     6 5
00000130   01 35 00 03 0B 06 34 00  6A 01 00 00 00 02 67 36    5    4 j     g6
00000140   00 00 00 09 33 00 03 3F  00 35 02 32 00 03 06 31       3  ? 5 2   1
00000150   00 09 30 00 03 31 00 35  02 2F 00 03 06 31 00 03     0  1 5 /   1  
00000160   34 00 03 31 00 03 3A 00  03 3A 00 35 04 2E 00 03   4  1  :  : 5 .  
00000170   0B 06 2D 00 57 01 00 00  00 01 57 0D FF FF FF
        - W     W
内存中找到的函数内容和文件解码后的内容是一致的。

点评

来个全部代码看看!  发表于 2019-1-14 14:29
发表于 2019-1-11 12:36:02 | 显示全部楼层
本帖最后由 yxp 于 2019-1-11 12:59 编辑

老哥哥,你这是32位的CAD系统吗?能不能看看你的 c:ttt 函数在64位CAD里的编码是否一致,以下16个字节一组。
E860E6E9FB7F0000 0000000000000000
58424A3100000000 38EB633100000000
0000000000000000 E860E6E9FB7F0000
0200000000000000 1021663100000000
88EB633100000000 0000000000000000
E860E6E9FB7F0000 0200000000000000


以下lisp函数可以检查某个指定lisp在内存里的数据

调用: (getmem c:ttt 76 8)  表示要查询 c:ttt 函数 76 个字节,每 8 个字节一组:



内存查询函数源码如下:
  1. (defun getmem (cm size sec / hex ss m n sum)  (defun isACAD64 ()
  2.   (= 17(strlen(vl-prin1-to-string
  3.       (cadr (read (strcat "(" (vl-prin1-to-string +) ")"))))))
  4.   )
  5. (setq hex '(("F" . 15)("E" . 14)("D" . 13)("C" . 12)("B" . 11)
  6.     ("A" . 10)("9" . 9)("8" . 8)("7" . 7)("6" . 6)("5" . 5)
  7.     ("4" . 4)("3" . 3)("2" . 2)("1" . 1)("0" . 0)))
  8. (if (= 'SUBR (type cm))(progn
  9.     (setq ss (substr (vl-prin1-to-string cm) 9 (if (isACAD64) 16 8))
  10.         ss (strcase ss)
  11.         n (strlen ss)
  12.         m 0 sum 0)
  13.     (while (> n 0)
  14.     (setq sum (+ (* (cdr (assoc (substr ss n 1) hex)) (expt 16 m)) sum)
  15.         n (1- n) m (1+ m)))
  16.     (setq dwx (vlax-get-or-create-object "DynamicWrapperX"))
  17.     (vlax-invoke DWX 'MemRead sum size sec)
  18.     )
  19. )
  20. )


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
 楼主| 发表于 2019-1-14 07:37:15 | 显示全部楼层
yxp 发表于 2019-1-11 12:36
老哥哥,你这是32位的CAD系统吗?能不能看看你的 c:ttt 函数在64位CAD里的编码是否一致,以下16个字节一组 ...

是的,我用32位的工具很熟。64位下总感觉工具不好用
发表于 2018-12-6 11:51:28 来自手机 | 显示全部楼层
又有新发现?
发表于 2018-12-10 09:56:15 | 显示全部楼层
谢谢!分享程序!!!
发表于 2018-12-10 14:18:48 | 显示全部楼层
支持大师继续研究
发表于 2018-12-11 09:17:12 | 显示全部楼层
加油加油,继续研究
 楼主| 发表于 2019-1-9 07:46:48 | 显示全部楼层
USER2128 发表于 2018-12-10 14:18
支持大师继续研究

谢谢你的鼓励,不是什么大师
发表于 2019-1-9 14:14:37 | 显示全部楼层
核心代码,需要核心人物。
发表于 2019-1-11 11:01:08 | 显示全部楼层
拜读了,顶一下!!!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2025-5-16 15:52 , Processed in 0.178860 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表