明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
楼主: baitang36

[经验] fas文件格式研究

    [复制链接]
 楼主| 发表于 2018-9-4 21:57:33 | 显示全部楼层
本帖最后由 baitang36 于 2018-9-12 21:39 编辑
zixuan203344 发表于 2018-9-4 17:34
52破解上应该是复制的你的帖子吧

那是我的马甲,备份
发表于 2018-9-6 07:34:11 | 显示全部楼层

破冰之旅!支持作者!
发表于 2018-9-7 01:10:47 | 显示全部楼层
本帖最后由 yxp 于 2018-9-8 19:59 编辑

baitang36 的思路,我试了一下用 lisp 也可以解密 fas,不用汇编程序,降低研究门槛。有兴趣的来和  baitang36  一起把 fas 文件逆向工程了

在cad里加载运行 unfas
请到32楼下载新版,fas解密lisp运行需要dwx环境

记事本打开fas文件

  1. ;;fas 文件解密  by yxp_xa 2018年9月7日
  2. ;;按 baitang36 的思路将 fas 文件解密,似乎作用不大,和 lisp 源码相比还有一些差距
  3. ;;解密后的文件以二进制存储,需要用编辑器的 HEX 模式查看
  4. (vl-load-com)
  5. (defun c:unfas()
  6.     (or fasPath (setq fasPath ""))
  7.     (setq ps (getfiled "打开 .fas 文件" fasPath "fas" 0))
  8.     (if ps (progn
  9.         (or dwx (setq dwx (vlax-create-object "DynamicWrapperX")))

  10.         (princ "\n正在载入fas文件...")
  11.         (setq fasSize (Load_Fasfile_mem (setq fasPath ps)))
  12.         (princ (strcat "成功载入 " (itoa fasSize) " 字节"))

  13.         (princ "\n正在分析...")
  14.         (Fas_Section_data)

  15.         (princ "\n正在解密...")
  16.         (Decry_Fas_data)

  17.         (princ "\n正在导出解密fas文件...")
  18.         (Save_Fas_text)
  19.     ))
  20.     (princ)
  21. )

  22. ;;保存 fas 解密后的代码,仅第二段
  23. (defun Save_Fas_text( / n)
  24.    (setq file (strcat (vl-filename-directory fasPath) "\\"
  25.            (vl-filename-base fasPath) "_bak.bin"))
  26.     (setq n (length DecList) o 0)
  27.     (setq fp (vlax-invoke dwx 'MemAlloc n 1))
  28.     (foreach x DecList
  29.         (vlax-invoke dwx 'NumPut x fP o "b")
  30.         (setq o (1+ o))
  31.     )
  32.   (vlax-invoke dwx 'Register "kernel32" "CreateFileW" "i=wllplll" "r=l")
  33.   (vlax-invoke dwx 'Register "kernel32" "WriteFile" "i=pplpl" "r=l")
  34.   (vlax-invoke dwx 'Register "kernel32" "CloseHandle" "i=p" "r=l")
  35.   (setq FileID (vlax-invoke dwx 'CreateFileW file 1073741824 1 0 4 128 0))
  36.   (setq FineNumber (vlax-invoke dwx 'MemAlloc 4 1))
  37.   (vlax-invoke dwx 'WriteFile FileID fp n FineNumber 0)
  38.   (vlax-invoke dwx 'CloseHandle FileID)
  39.   (vlax-invoke dwx 'NumGet FineNumber)
  40.     (princ (strcat "\n解密文件已保存到: " file))
  41. )


  42. ;;fas文件解码,虽然dwx也可以运行汇编代码,但此处没有必要
  43. (defun Decry_Fas_data()
  44.     (setq seconDecList (mapcar 'Hex2Dec (Txt_Split secondHex " ")))
  45.     (setq n 1 key1 (car fasKey) key2 (cadr fasKey) DecList nil)
  46.     (setq kmax (- (length fasKey) 2)) ;;扣掉末尾字符串
  47.     (foreach x seconDecList
  48.         (setq DecList (cons (Boole 6 x key1 key2) DecList)
  49.             key1 key2
  50.             n (if (> n kmax) 0 (1+ n)) ;;key 指针越位归零
  51.             key2 (nth n fasKey))
  52.     )
  53.     (setq DecList (reverse DecList)) ;;解密后的fas,10进制
  54.     (setq HexList (mapcar 'Dec2Hex DecList)) ;;解密后的fas,16进制
  55. )


  56. ;;fas数据分析与分段
  57. (defun Fas_Section_data()
  58. ;;fas头文件
  59. ;;读入fas字符串,遇到 00 自动结束
  60.     (setq headFasText (vlax-invoke dwx 'StrGet fasPoint "s"))
  61.     (setq headList (Txt_Split headFasText "\r\n"))
  62.     (setq txt (vl-string-trim " " (cadr headList)))
  63.     (princ (strcat "\n头文件: " txt))
  64. ;;fas第一段
  65.     (setq firstAddr (+ (vl-string-search "$" headFasText) 1))
  66.     (setq firstSize (atoi (caddr headList)))    ;;得到第一段字节大小:121
  67.     (setq firstNum (atoi (last headList)))   ;;得到第一段变量个数: 14
  68.     ;;第一段hex编码
  69.     (setq firstHex (vlax-invoke DWX 'MemRead (+ fasPoint firstAddr) firstSize 1))
  70.     (princ (strcat "\n第一段,地址:" (Dec2Hex firstAddr) " 大小:" (itoa firstSize)))
  71. ;;fas第二段
  72.     (setq secondAddr (+ firstAddr firstSize 1))
  73.     (setq ptxt (vlax-invoke dwx 'MemAlloc 16 1));;分配16个字节接收15个字符
  74.     (vlax-invoke dwx 'MemCopy (+ fasPoint secondAddr) ptxt 15)
  75.     (setq txt (vlax-invoke dwx 'StrGet ptxt "s"))
  76.     (setq posiTxt (vl-string-search "$" txt)) ;;第二段的说明文字
  77.     (setq txt (vl-string-left-trim "\r\n" txt))
  78.     (setq Ltxt (Txt_Split txt " "))
  79.     (setq secondSize (atoi (car Ltxt))) ;;第二段字节大小
  80.     (setq secondNum (atoi (cadr Ltxt)))  ;;第二段变量个数
  81.     (setq secondAddr (+ secondAddr posiTxt 1))
  82.     ;;第二段hex编码
  83.     (setq secondHex (vlax-invoke DWX 'MemRead (+ fasPoint secondAddr) secondSize 1))
  84.     (princ (strcat "\n第二段,地址:" (Dec2Hex secondAddr) " 大小:" (itoa secondSize)))
  85. ;;fas第三段 提取 fasKey
  86.     (setq thirdAddr (+ secondAddr secondSize))
  87.     (setq thirdSize (vlax-invoke dwx 'NumGet fasPoint thirdAddr "b")) ;;第三段字节大小
  88.     ;;第三段hex编码
  89.     (setq thirdHex (vlax-invoke DWX 'MemRead (+ fasPoint thirdAddr 1) thirdSize 1))
  90.     (setq fasKey (mapcar 'Hex2Dec (Txt_Split thirdHex " ")))
  91.     (princ (strcat "\n第三段,地址:" (Dec2Hex thirdAddr) " 大小:" (itoa thirdSize)))
  92. ;;fas第四段
  93.     (setq fourthAddr (+ thirdAddr thirdSize 1))
  94.     (setq fourthTxt (vlax-invoke dwx 'StrGet (+ fourthAddr fasPoint 1) "s"))
  95.     (setq fourthTxt (vl-string-left-trim ";" fourthTxt))
  96.     (princ (strcat "\n第四段,地址:" (Dec2Hex fourthAddr) " 编译日期:" fourthTxt))
  97. )



  98. ;;读入fas文件至内存
  99. ;;成功返回载入文件的大小,失败则返回nil,文件指针以全局变量fasPoint返回
  100. (defun Load_Fasfile_mem(file / FileID tf FileSize FineNumber fsize)
  101. (if (setq tf (findfile file))(progn
  102.     (vlax-invoke dwx 'Register "kernel32" "CreateFileW" "i=wllplll" "r=l")
  103.     (vlax-invoke dwx 'Register "kernel32" "ReadFile" "i=pplpl" "r=l")
  104.     (vlax-invoke dwx 'Register "kernel32" "CloseHandle" "i=p" "r=l")
  105.     (setq FileID (vlax-invoke dwx 'CreateFileW tf 1 1 0 3 128 0))
  106.     (setq FileSize (vl-file-size tf))
  107.     (setq fasPoint (vlax-invoke dwx 'MemAlloc FileSize 1))
  108.     (setq FineNumber (vlax-invoke dwx 'MemAlloc 4 1))
  109.     (vlax-invoke dwx 'ReadFile FileID fasPoint FileSize FineNumber 0)
  110.     (vlax-invoke dwx 'CloseHandle FileID)
  111.     (setq fsize (vlax-invoke dwx 'NumGet FineNumber))
  112. ))
  113. )

  114. ;;字符分割
  115. (defun Txt_Split (str sep / Pos1 Pos2 NStr)
  116. (setq Pos2 1)
  117. (while (setq Pos1 (vl-string-search sep str Pos1))
  118.     (setq NStr (cons (substr str Pos2
  119.     (if (= Pos2 1) Pos1 (- (1+ Pos1) Pos2))) NStr)
  120.         Pos2 (1+ (+ (strlen sep) Pos1))
  121.         Pos1 (+ Pos1 (strlen sep)))
  122.     )
  123. (reverse (cons (substr str Pos2) NStr))
  124. )

  125. ;;十六进制转10进制
  126. (defun Hex2Dec(h)
  127. (setq hex (strcase h) n (strlen hex) m 0 sum 0
  128.    con '(("0" 0)("1" 1)("2" 2)("3" 3)("4" 4)("5" 5)("6" 6)("7" 7)("8" 8)
  129.        ("9" 9)("A" 10)("B" 11)("C" 12)("D" 13)("E" 14)("F" 15)))
  130. (while (> n 0)
  131.    (setq sum (+ (* (cadr (assoc (substr hex n 1) con))(expt 16 m)) sum)
  132.            m (1+ m) n (1- n)
  133. )) sum
  134. )



程序运行需要 dwx 的支持 (for x64),请自行下载并注册 dll




本帖子中包含更多资源

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

x

点评

好厉害,有最新研究成果吗  发表于 2023-9-17 16:59
很厉害的lisp编程水平  发表于 2018-11-3 20:07

评分

参与人数 1明经币 +1 收起 理由
USER2128 + 1 很给力!

查看全部评分

回复 支持 6 反对 0

使用道具 举报

发表于 2018-9-7 16:35:43 | 显示全部楼层
有一段时间没上论坛,没想到又有大佬出现,厉害了,学您学习
发表于 2018-9-7 19:14:58 | 显示全部楼层
14不是什么长度,好像是这个段的变量个数
 楼主| 发表于 2018-9-8 08:28:15 | 显示全部楼层
本帖最后由 baitang36 于 2018-9-8 08:38 编辑

研究了几天,成果向大家汇报一下,欢迎感兴趣的朋友和我一起研究,我的qq5520971。
乐趣存在于过程中,也许最终完成的时候也就没什么兴趣了。这就像猜谜语,谜底出来的时候也就索然无味了。
先看下面这个小程序:
(defun c:ddd ()
  (setq a 187)
  (setq b 170)
  (setq        c (+ a b))
  (princ c)
  )
(defun c:eee ()
  (setq a 188)
  (setq b 171)
  (setq        c (+ a b))
  (princ c)
  
)
(defun c:fff ()
  (setq dd 189)
  (setq ee 172)
  (setq        ff (+ a b))
  (princ ff)  
)
大家可能觉得数字挺奇怪,为什么用170 171 172 之类的数字?
十进制的170是16进制的AA,,171是AB,172是AC,187是BB,188是BC,
用这些特殊数字的目的是为了在编译后的文件中容易找到:-)。
编译解码后的文件是这样的,当然是用16进制显示的。
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 31 33 32 0D 0A 39  20 24 14 00 00 00 00 33     132  9 $     3
00000030   BB 00 00 00 06 08 00 33  AA 00 00 00 06 07 00 03   ?     3?      
00000040   08 00 03 07 00 35 02 06  00 03 06 05 00 03 05 00        5         
00000050   35 01 04 00 03 16 14 00  00 00 00 33 BC 00 00 00   5          3?  
00000060   06 08 00 33 AB 00 00 00  06 07 00 03 08 00 03 07      3?         
00000070   00 35 02 06 00 03 06 05  00 03 05 00 35 01 04 00    5          5   
00000080   03 16 14 00 00 00 00 33  BD 00 00 00 06 03 00 33          3?     3
00000090   AC 00 00 00 06 02 00 03  08 00 03 07 00 35 02 06   ?           5  
000000A0   00 03 06 01 00 03 01 00  35 01 04 00 03 16 24 0D           5     $
000000B0   0A 32 34 34 20 39 20 24  14 01 01 01 00 32 00 32    244 9 $     2 2
000000C0   51 2A 39 01 00 5B 43 3A  46 46 46 00 43 3A 45 45   Q*9  [C:FFF C:EE
000000D0   45 00 00 56 76 6C 2D 41  43 41 44 2D 64 65 66 75   E  Vvl-ACAD-defu
000000E0   6E 00 00 5B 43 3A 44 44  44 00 00 01 01 43 00 00   n  [C:DDD    C  
000000F0   06 00 0A 32 58 33 84 00  00 00 2A 32 2C 32 58 2A      2X3?  *2,2X*
00000100   32 00 32 2C 2A 39 03 00  5B 46 46 00 45 45 00 44   2 2,*9  [FF EE D
00000110   44 00 50 52 49 4E 43 00  43 00 2B 00 42 00 41 00   D PRINC C + B A
00000120   00 5C 00 00 43 00 00 09  00 0A 5C 00 00 32 58 5B    \  C     \  2X[
00000130   43 3A 46 46 46 00 00 3A  5C 00 00 32 2C 5B 43 3A   C:FFF  :\  2,[C:
00000140   45 45 45 00 00 3A 5C 00  00 32 00 5B 43 3A 44 44   EEE  :\  2 [C:DD
00000150   44 00 00 3A 01 43 06 00  03 00 1C 14 01 00 00 00   D  : C         
00000160   09 05 00 0A 57 00 00 00  00 09 08 00 06 04 00 09       W           
00000170   04 00 35 01 03 00 01 0A  09 04 00 0A 57 00 00 00     5         W   
00000180   00 09 07 00 06 02 00 09  02 00 35 01 03 00 01 0A             5     
00000190   09 02 00 0A 57 00 00 00  00 09 06 00 06 01 00 09       W           
000001A0   01 00 35 01 03 00 01 0A  09 01 00 16 15 00 19 34     5            4
000001B0   32 3F CC 0A 3B 66 61 73  34 20 63 72 75 6E 63 68   2??;fas4 crunch
000001C0   0A 3B 24 3B 41 39 2F 34  2F 31 38                             ;$;A9/4/18
经过多次试验,现在可以弄明白的是,从地址2A开始是程序代码,它是没加密的,也就是
这部分代码:
Offset           0  1  2   3   4    5    6  7   8   9    A   B  C   D   E   F
00000020                                                      14 00 00 00 00 33     132  9 $     3
00000030   BB 00 00 00 06 08 00 33  AA 00 00 00 06 07 00 03   ?     3?      
00000040   08 00 03 07 00 35 02 06  00 03 06 05 00 03 05 00        5         
00000050   35 01 04 00 03 16 14 00  00 00 00 33 BC 00 00 00   5          3?  
00000060   06 08 00 33 AB 00 00 00  06 07 00 03 08 00 03 07      3?         
00000070   00 35 02 06 00 03 06 05  00 03 05 00 35 01 04 00    5          5   
00000080   03 16 14 00 00 00 00 33  BD 00 00 00 06 03 00 33          3?     3
00000090   AC 00 00 00 06 02 00 03  08 00 03 07 00 35 02 06   ?           5  
000000A0   00 03 06 01 00 03 01 00  35 01 04 00 03 16
这里的数据  14 00 00 00 00 33 BB 00 00 00 06 08 00 33  AA 00 00 00 06 07 00
03 08 00 03 07 00 35 02 06  00 03 06 05 00 03 05 00  35 01 04 00 03 16
就是程序代码:
( (setq a 187)
  (setq b 170)
  (setq        c (+ a b))
  (princ c)
  )
14是开头,16是结尾,当然,都是16进制。
33 BB 00 00 00 06 08 00这一句就是(setq a 187) ,十进制的187就是16进制的BB
BB 00 00 00占用4个字节,说明是32位整数。
33应该有某种意义,暂不管它。
06应该是相当于命令setq
08 00占用两个字节,数字在内存中的存放时低位在前,高位在后的。08 00也就是数字8
在这里应该是表示变量a,它是第8号?
按以上规律再来看下一句
33  AA 00 00 00 06 07 00就是(setq b 170)
AA 00 00 00是数字170,07 00是7号变量?
a是8,b是7,看来变量的存放顺序是倒着的,先用的序号大,后用的序号小。
现在遇到的问题是,这个序号是怎么来的?等我研究后,再跟大家分享。
等我好消息,今天就到这里。

补充一下,因为资料特别缺乏,文中观点都是猜测加试验验证,有可能是错的,欢迎大家提出经过验证的相反意见。




本帖子中包含更多资源

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

x

点评

yxp
建议16进制数用 0x08 或 08h 表示,看着看着就进制就乱了。  发表于 2018-9-8 14:00
 楼主| 发表于 2018-9-8 08:49:37 | 显示全部楼层
本帖最后由 baitang36 于 2018-9-8 12:20 编辑
yxp 发表于 2018-9-7 01:10
地址 0x00 - 0x21:  从0D0A 开始到 0D0A结束,共计34字节。
0D 0A 的十进制就是 13 10,转换成ASCII码就是 ...

14是某段程序的开头,16是结尾 这里是字符串个数+1?
 楼主| 发表于 2018-9-8 08:53:24 | 显示全部楼层
fl202 发表于 2018-9-4 11:17
厉害!

强贴占位。

等将来再回答这个问题,现在刚开始研究
发表于 2018-9-8 08:57:02 | 显示全部楼层
利害,先做个标记.
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-11-25 12:51 , Processed in 0.162296 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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