手工反编译一个fas小程序实验
本帖最后由 baitang36 于 2018-10-9 16:17 编辑这个小程序的作者是:updoc,
下载连接是:http://bbs.mjtd.com/plugin.php?id=imc_attachplug:attachad&aid=MTAxNjc5fDUwZTliMDAxfDE1MzkwNjM3MDd8NzMwMjUyMHwxNzgzMTM%3D
解码后是这样的:
Offset 01234567 89ABCDEF
00000000 0D 0A 20 46 41 53 34 2D46 49 4C 45 20 3B 20 44 FAS4-FILE ; D
00000010 6F 20 6E 6F 74 20 63 6861 6E 67 65 20 69 74 21 o not change it!
00000020 0D 0A 31 36 30 0D 0A 3231 20 24 14 00 00 00 00 16021 $
00000030 35 00 14 00 03 0A 09 1300 35 01 12 00 03 35 01 5 5 5
00000040 11 00 03 35 01 10 00 0306 0F 00 03 0F 00 33 16 5 3
00000050 C9 33 01 35 02 0E 00 0367 57 00 00 00 09 0D 00 ? 5 gW
00000060 35 01 0C 00 03 32 0E 3310 27 00 00 09 13 00 35 5 2 3 ' 5
00000070 01 12 00 03 35 02 0B 0003 35 01 11 00 03 35 01 5 5 5
00000080 0A 00 03 35 02 09 00 0335 02 08 00 03 67 0E 00 5 5 g
00000090 00 00 09 07 00 35 01 0600 03 0A 57 0F 00 00 00 5 W
000000A0 09 05 00 35 01 06 00 030A 35 00 04 00 03 0A 57 5 5 W
000000B0 0F 00 00 00 09 03 00 3501 06 00 03 0A 35 00 04 5 5
000000C0 00 03 0A 09 02 00 0B 0601 00 16 24 0D 0A 33 31 $31
000000D0 37 20 35 20 24 14 01 0101 00 32 00 32 21 2A 39 7 5 $ 2 2!*9
000000E0 01 00 56 76 6C 2D 41 4341 44 2D 64 65 66 75 6E Vvl-ACAD-defun
000000F0 00 00 5B 43 3A 54 54 0000 01 01 43 00 00 04 00 [C:TT C
00000100 0A 32 00 33 A0 00 00 002A 39 01 00 5B 41 00 00 2 3?*9[A
00000110 55 02 00 08 00 B3 CC D0F2 D6 B4 D0 D0 1C 00 0A U 程序执行
00000120 20 20 20 B3 CC D0 F2 D2D1 B9 FD C6 DA 0A 20 20 程序已过期
00000130 20 C7 EB C1 AA CF B5 D7F7 D5 DF 5B 45 58 49 54 请联系作者[EXIT
00000140 00 00 55 01 00 1A 00 0A20 20 20 B3 CC D0 F2 B9 U 程序
00000150 FD C6 DA 0A 20 20 20 C7EB C1 AA CF B5 D7 F7 D5 ? 请联系作
00000160 DF 5B 41 4C 45 52 54 0000 55 01 00 0D 00 0A 20 遊ALERTU
00000170 20 20 D6 B4 D0 D0 B3 CCD0 F2 41 5B 3E 00 4E 54 执行程序A[> NT
00000180 48 00 56 4C 2D 53 54 5249 4E 47 2D 3E 4C 49 53 H VL-STRING->LIS
00000190 54 00 2A 00 41 53 43 4949 00 00 55 01 00 01 00 T * ASCIIU
000001A0 33 5B 3C 3D 00 43 44 4154 00 41 54 4F 49 00 52 3[<= CDAT ATOI R
000001B0 54 4F 53 00 47 45 54 5641 52 00 00 55 01 00 05 TOS GETVARU
000001C0 00 63 64 61 74 65 5B 564C 2D 4C 4F 41 44 2D 43 cdate[VL-LOAD-C
000001D0 4F 4D 00 00 5C 00 00 4300 00 15 00 0A 5C 00 00 OM\C \
000001E0 32 00 5B 43 3A 54 54 0000 3A 01 43 04 00 01 00 2 [C:TT: C
000001F0 1C 14 01 00 00 00 09 0300 0A 57 00 00 00 00 09 W
00000200 04 00 06 02 00 09 02 0035 01 01 00 01 0A 09 02 5
00000210 00 16 18 00 E8 7E 4F 8F80 75 04 8A 0A 3B 66 61 鑯O 本帖最后由 baitang36 于 2018-10-9 16:44 编辑
整理一下字符串:
编号(16进制) 字符串内容
1 A
2 程序执行
3 程序已过期 请联系作者
4 EXIT
5 程序过期 请联系作者
6 ALERT
7 执行程序A
8 >
9 NTH
A VL-STRING->LIST
B *
C ASCII
D 3
E <=
F CDAT
10 ATOI
11 RTOS
12 GETVAR
13 cdate
14 VL-LOAD-COM
15 C:TT
把程序代码按指令切开,每行一个指令,分析如下:
14 00 00 00 00 ;函数开始,参数个数为0
35 00 14 00 03 0A ;执行14号字符串,参数个数为0,VL-LOAD-COM ;(VL-LOAD-COM)
09 13 00 ;将13号字符串压入堆栈,cdate
35 01 12 00 03 ;执行12号字符串,1个参数,GETVAR ;(GETVAR “cdate”)
35 01 11 00 03 ;执行11号字符串,1个参数 RTOS;; (RTOS
35 01 10 00 03 ;执行10号字符串,1个参数 ATOI;;(ATOI
06 0F 00 ;对F号字符串赋值 CDAT ;(setq CDAT (ATOI (RTOS (GETVAR “cdate”))))
03 0F 00 ;压入堆栈0Fh号字符串,CDAT
33 16 C9 33 01 ;压入堆栈一个数字133C916h,十进制是20171030
35 02 0E 00 03 ;执行E号字符串,<= ;(<= CDAT 20171030)
67 57 00 00 00 ;判断,如果成立,跳过57H个字符串 ;(IF (<= CDAT 20171030) )()())
09 0D 00 ;将D号字符串压入堆栈,"3"
35 01 0C 00 03 ;执行C号字符串,1个参数,ASCII;(ASCII “3”)
32 0E ;将数字0eh压入堆栈,也就是十进制14
33 10 27 00 00 ;将数字2710h压入堆栈,也就是十进制10000
09 13 00 ;将13号字符串压入堆栈,cdate
35 01 12 00 03 ;执行12号字符串,1个参数,GETVAR;(GETVAR “cdate”)
35 02 0B 0003 ;执行B号字符串,2个参数,* ; (* (GETVAR “cdate”)10000 )
35 01 11 00 03 ;执行11号字符串,1个参数,RTOS;(RTOS (* (GETVAR “cdate”)10000))
35 01 0A 00 03 ;执行A号字符串,1个参数,VL-STRING->LIST ;(VL-STRING->LIST (RTOS (* (GETVAR “cdate”)10000)))
35 02 09 00 03 ;执行9号字符串,2个参数,NTH ;(NTH 14(VL-STRING->LIST (RTOS (* (GETVAR “cdate”)10000))))
35 02 08 00 03 ;执行8号字符串,2个参数,> (> (ASCII “3”)(NTH 14(VL-STRING->LIST (RTOS (* (GETVAR “cdate”)10000)))))
67 0E 00 00 00 ;判断,如果成立,跳过0EH个字符串,(iF (> (ASCII “3”)(NTH 14(VL-STRING->LIST (RTOS (* (GETVAR “cdate”)10000)))))(ALERT “执行程序A”)(ALERT “程序过期 请联系作者”))
09 07 00 ;将7号字符串压入堆栈
35 01 0600 03 0A;执行6号字符串,1个参数,ALERT ;(ALERT “执行程序A”)
57 0F 00 00 00 ;跳过0fh个字节
09 05 00 ;将5号字符串压入堆栈,“程序过期 请联系作者”
35 01 06 00 030A;执行6号字符串,1个参数,ALERT ;(ALERT “程序过期 请联系作者”)
35 00 04 00 03 0A ;执行4号字符串,0个参数,;(exit)
57 0F 00 00 00 ;跳过0fh个字节
09 03 00 ;将3号字符串压入堆栈,“程序已过期 请联系作者”
35 01 06 00 03 0A ;执行6号字符串,1个参数,ALERT;(ALERT “程序已过期 请联系作者” )
35 00 04 00 03 0A ;执行4号字符串,0个参数,;(exit)
09 02 00 ;将2号字符串压入堆栈,"程序执行"
0B 0601 00 ;对1号字符串赋值,(setq A "程序执行")
16 ;函数结束
总结一下上面的内容,源代码如下:
(defun C:TT()
(VL-LOAD-COM)
(setq CDAT (ATOI (RTOS (GETVAR “cdate”))))
(IF (<= CDAT 20171030) )(iF (> (ASCII “3”)(NTH 14(VL-STRING->LIST (RTOS (* (GETVAR “cdate”)10000)))))(ALERT “执行程序A”)(progn(ALERT “程序过期 请联系作者”)(exit)))(PROGN(ALERT “程序已过期 请联系作者”
)(exit)))(setq A "程序执行")
)
网上十年前就有参考资料吧,只是把半成品放出来。我也搞了很久,一直没搞定,后来有人搞出来了,卖3k,我嫌贵没买,因为我觉得lisp还是个性化比较强的东西,我想实现的别人都没有做过或者说做得非常好,没有注释,也没有文档,小程序还好,大程序读起来能让你吐血。个人比较喜欢明经和晓东分享的有说明的源码。而且,lisp能实现的基本都是很有限的功能,只有依托其它语言、其它程序才能更强大。 什么叫做反编译??? 本帖最后由 baitang36 于 2018-10-9 16:19 编辑
mikewolf2k 发表于 2018-10-9 16:12
什么叫做反编译???
就是把编译后的fas文件变回lsp源码 baitang36 发表于 2018-10-9 16:13
就是把编译后的fas文件变回lsp源码
发帖时候没看到第二个帖子。
话说回来,研究这个有什么意义?就算真的能反编译,花的时间也比重新写要多。 本帖最后由 baitang36 于 2018-10-9 16:41 编辑
mikewolf2k 发表于 2018-10-9 16:29
发帖时候没看到第二个帖子。
话说回来,研究这个有什么意义?就算真的能反编译,花的时间也比重新写要多 ...
意义在于学习别人的代码。
特殊的技巧,特殊功能等。
有时候想知道别人是怎么实现的。
这个也是不违反著作权法和软件保护条例的。用于学习、研究目的,不存在盗版的问题。
只有你用别人的软件来赚钱,这才算盗版。
《计算机软件保护条例》第十七条 为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬。
要不随便找个没有源代码的fas来反编译试试?acad自带的就行。 mikewolf2k 发表于 2018-10-9 16:40
要不随便找个没有源代码的fas来反编译试试?acad自带的就行。
主要是太麻烦,手工操作,程序大了会累死人的 这是作者提供的源代码:
(DEFUN C:TT()
(vl-load-com)
(setq cdat (atoi (rtos (getvar "cdate"))))
(if (<= cdat 20171030)
(progn
(if (> (ascii "3") (NTH 14 (vl-string->list(rtos (* 10000 (getvar "cdate"))))))
(alert "\n 执行程序A")
(progn
(alert "\n 程序过期\n 请联系作者")
(exit)
)
)
)
(progn
(alert "\n 程序已过期\n 请联系作者")
(exit)
)
)
(setq a "程序执行")
)
看来我处理progn还有问题
琢磨一下可能没结果,但也没坏处,专研的精神可嘉。