Board logo

标题: 人工构造 ascode [打印本页]

作者: CrLf    时间: 2013-1-21 20:02     标题: 人工构造 ascode

本帖最后由 CrLf 于 2015-5-20 01:09 编辑

参考ascode 的一些资料汇编一贴中汇总的帖子内容,其实在 debug 里逐步跟踪就能了解如何具体实现了,只是很累罢了。
其实我也只是掌握了基本思路,水平不高,现分享一些心得以供参考,或有疏漏敬请指正。
手头最好有 win7 自带的计算器,xp 可用 Megatops BinCalc 替补,以便进行 16to10、10to16、xor、sub、and 等运算。
----------------------------------------------------------------------------------
首先来了解下可以用到的指令,我构造了一个测试文本(内容为 00 '&&&&' 01 '&&&&' 02 '&&&&' 依此类推...),反汇编观察到分布在 20~7F 范围内可用的 ascode 指令大致有(此处由 email10t 在本贴 26 楼补充):
  1. *:  and sub xor cmp j*  daa das aaa  inc dec  push pop pusha popa imul insb insw outsb outsw
复制代码
emu8086 不能直接使用 insb insw outsb outsw,需要 db (define byte)
ascode 不能直接使用 jnle 指令
----------------------------------------------------------------------------------
结合自己的经验,简单解释下:
  1. *: 表示所有数据段前缀,例如 ES: 和 DS:
  2. j* 表示短距离的条件跳转,例如 jz 和 jnz
  3. and 和 cmp 只支持对寄存器和地址的运算比较,不支持寄存器之间的直接运算
  4. sub 和 xor 支持对 ax、al 的所有操作,对 dx 等其他寄存器操作时有时需要使用不可见字符
  5. dec 和 inc 可用于整个操作任何寄存器,若只操作高位或低位则需不可见字符
  6. push 和 pop 对大部分寄存器操作的指令都为可见字符,对段寄存器和标志位操作时除外
复制代码
事实上,有些特殊内容是可以硬凑出来的,比如中括号内的内容【@ECHO  OFF&REM  】其实也可以直接写入到 com 中执行,只是这基本实现不了什么功能,只能作为另一种嵌入文本的思路罢了。

我们发现,汇编时常用的 mov、int、add、ret、jmp 等命令在这里都不能直接使用,j*条件跳转、cmp 等也颇受限制。
但是要感谢机器语言的发明者和 ascii 标准的制定者没有赶尽杀绝,反汇编前辈们的 ascode 可以略窥一二,下面就简单介绍下如何用有限的指令实现所有指令的功能,试举有代表性的几例,其他指令的实现请自行举一反三:
指令达到类似效果的 ascode
mov ax,bx push bx
pop ax
mov al,15若 ax=0,可以:
xor al,35
xor al,20

若 ax=60,则可以:
sub al,4e
add al,32 sub al,60
sub al,6e
mov ah,15 参考前文
假设 ah 为 0,则可:
xor ax,3520
xor ax,2020

mov ax,0
假设 bx=0(其他为 0 的寄存器也可),那是最方便的了:
push bx
pop ax


假设 di+bp=c0 且 cs=ds,则可以从内存中获取:
and ax,[di+bp+3f]
int 21
(这个内容比较重要,
如 jmp、loop 等以及
其他无法直接实现的指令
都可以用这种办法解决)
假设 ax=0(默认),且 xor al,60 位置位于 ds:100,则可:
xor al,60
;见前文,等于 mov ax,60
push ax
push ax
pop di
pop bp
;见前文,等于 mov di,ax 以及 mov bp,ax
sub [di+bp+49],al
;di+bp+49=109,即 db 2d 位置,2d-al=2d-60,运算后该地址值变为 cd
db 2d 21
;int 21 的机器码为 cd 21,这里用 2d 占位,执行上一条指令后这里会变为 int 21

作者: CrLf    时间: 2013-1-21 20:03

本帖最后由 CrLf 于 2014-11-26 00:32 编辑

附上 demon 大师的博文链接:ASCII Assembly技术简介
可惜那个“下面的网站总结了每个可打印的ASCII字符所对应的汇编指令”的链接失效了,印象中内容很详尽,当时直接导致我放弃更新此贴
---------------------------------------------------------------------
本站站内搜索 ascode 和 ascii assembly 得到这些相关帖子链接:
输入密码但不显示既隐藏输入密码的批处理(20090420)
屏蔽命令行密码 5楼
小型二进制文件ASCII编码器
【挑战】批处理如何创建仅含一个nul字符的文件 14楼
批处理与其他语言混合编程2
[方案汇总]批处理隐藏运行的11种思路(2009-04-18)
怎样让屏显的结果的同时写入到到文件中?
文本转URL编码
批处理用set代替choice怎么写?
求一段识别文件类型的BAT代码,也就是判断后缀名
批处理中 回车键的问题
[挑战]如何不换行输出以等号或引号开头的行? 14楼
只1k的延迟程序:sleep.com
ascode 的一些资料汇编
ascode 的 encode/decode 算法
ascode 的 encode/decode 算法2
ascode 应用之 仿控制台全屏效果 full.com
ascode 应用之 获取输入字符 getch.com
ascode 应用之 获取输入字符 getc.com
ascode 应用之 不换行显示字符串 put.com
ascode 应用之 将光标移动到指定位置 xy.com
ascode 应用之 存取文件 encode.com/decode.com
ascode 应用之 界面神器syxq便携版 syxq.com (Portable)
作者: CrLf    时间: 2013-1-21 20:03

本帖最后由 CrLf 于 2016-7-14 13:31 编辑

贴一下以前测试得出的一点成果,其实顶楼已经提到了,只是比较概括
ascode可用指令大概有这些:
  1. *:  and sub xor cmp j*  daa das aaa  inc dec  push pop pusha popa imul insb insw outsb outsw
复制代码
可见字符和控制字符中的少数字符对应的指令是可以用于初始的 ascode 的,请见下表(这个结果是碰撞所得,可能不完整,但表中列出的应该都能用)

控制字符:
  1. 00-05 add *
  2. 06 push es
  3. 07 pop es
  4. 08-0d or *
  5. 0e push cs
  6. 0f 无
  7. 10-15 adc *
  8. 16 push ss
  9. 17 pop ss
  10. 18-1d sbb *
  11. 1e push ds
  12. 1f pop ds
复制代码
可见字符:
  1. 20-25 and *
  2. 26 es:
  3. 27 daa
  4. 28-2d sub *
  5. 2e cs:
  6. 2f das
  7. 30-35 xor *
  8. 36 ss:
  9. 37 aaa
  10. 38-3d cmp [*],*
  11. 3e ds:
  12. 3f aas
  13. 40 inc ax
  14. 41 inc cx
  15. 42 inc dx
  16. 43 inc bx
  17. 44 inc sp
  18. 45 inc bp
  19. 46 inc si
  20. 47 inc di
  21. 48 dec ax
  22. 49 dec cx
  23. 4a dec dx
  24. 4b dec bx
  25. 4c dec sp
  26. 4d dec bp
  27. 4e dec si
  28. 4f dec di
  29. 50 push ax
  30. 51 push cx
  31. 52 push dx
  32. 53 push bx
  33. 54 push sp
  34. 55 push bp
  35. 56 push si
  36. 57 push di
  37. 58 pop ax
  38. 59 pop cx
  39. 5a pop dx
  40. 5b pop bx
  41. 5c pop sp
  42. 5d pop bp
  43. 5e pop si
  44. 5f pop di
  45. /********
  46. 区间 60~6f 由 email10t 在本贴 16 楼补充
  47. 区间 62、63、66、67 由 sj157250 在本贴 34 楼继续补充
  48. debug 无法正常汇编/反汇编这部分的指令,但可以正常运行
  49. 60 pusha
  50. 61 popa
  51. 62 BOUND
  52. 63 ARPL Ew,Rw
  53. 64 fs:
  54. 65 gs:
  55. 66 push dword * | Operand Size Prefix
  56. 67 imul dword * | Address Size Prefix
  57. 68 push word *
  58. 69 imul word *
  59. 6a push byte *
  60. 6b imul byte *
  61. 6c insb
  62. 6d insw
  63. 6e outsb
  64. 6f outsw
  65. 区间结束
  66. **********/
  67. 70 jo
  68. 71 jno
  69. 72 jb
  70. 73 jnb
  71. 74 jz
  72. 75 jnz
  73. 76 jbe
  74. 77 ja
  75. 78 js
  76. 79 jns
  77. 7a jpe
  78. 7b jpo
  79. 7c jl
  80. 7d jge
  81. 7e jle
  82. 7f jg
复制代码
不可见字符:
  1. 80-83 and word ptr *
  2. 84-85 test *
  3. 86-87 xchg *
  4. 88-8c mov *
  5. 8d lea *
  6. 8e mov
  7. 8f pop [*]
  8. 8f pop [*]
  9. 90 nop
  10. 91-97 xchg *
  11. 98 cbw
  12. 99 cwd
  13. 9a call
  14. 9b wait
  15. 9c pushf
  16. 9d popf
  17. 9e sahf
  18. 9f lahf
  19. a0-a3 mov *
  20. a4 movsb
  21. a5 movsw
  22. a6 cmpsb
  23. a7 cmpsw
  24. a8-a9 test *
  25. aa stosb
  26. ab stosw
  27. ac lodsb
  28. ad lodsw
  29. ae scasb
  30. af scasw
  31. b0-bf mov *
  32. c0-c1 无
  33. c2 ret *
  34. c3 ret
  35. c4 les *
  36. c5 lds *
  37. c6-c7 mov *
  38. c8-c9 无
  39. ca retf *
  40. cb retf
  41. cc int 3
  42. cd int *
  43. ce into
  44. cf iret
  45. d0-d3 shl *  (d0 ror;d2 rol)
  46. d4 aam *
  47. d5 aad
  48. d6 无
  49. d7 xlat
  50. d8 fsub dword ptr *
  51. d9 fldenv *
  52. da fisub dword ptr *
  53. db esc *
  54. dc fsub qword ptr *
  55. dd frstor *
  56. de fisub word ptr *
  57. df fbld tbyte ptr *
  58. e0 loopnz *
  59. e1 loopz *
  60. e2 loop *
  61. e3 jcxz
  62. e4-e5 in *
  63. e6-e7 out *
  64. e8 call *
  65. e9-eb jmp *
  66. ec-ed in *
  67. ee-ef out *
  68. f0 lock
  69. f1 无
  70. f2 repnz
  71. f3 repz
  72. f4 hlt
  73. f5 cmc
  74. f6 mul byte ptr *
  75. f7 mul word ptr *
  76. f8 clc
  77. f9 stc
  78. fa cli
  79. fb sti
  80. fc cld
  81. fd std
  82. fe-ff jmp [*]
复制代码
x86 的部分指令列表参见 pcl_test 在 35 楼的回帖
作者: CrLf    时间: 2013-1-21 20:03

本帖最后由 CrLf 于 2014-11-23 00:25 编辑

前文提到的 "@ECHO  OFF&REM" 反汇编的结果是这样:
  1. inc ax
  2. inc bp
  3. inc bx
  4. dec ax
  5. dec di
  6. and [bx+si],ah
  7. dec di
  8. inc si
  9. inc si
  10. es:
  11. push dx
  12. inc bp
  13. dec bp
  14. and [bx+si],ah
复制代码
这是个特例,而且也没有太大的实际作用
如果不对代码段的内存内容进行篡改,那连 int 指令都用不了,基本上干不了什么事
所以构造 ascode 的基本思路是用可见字符对应的指令修改即将后续执行的代码段内存,将其拼凑出 ascode 中本不存在的真实的机器码
作者: CrLf    时间: 2014-11-23 00:25

本帖最后由 CrLf 于 2015-5-7 23:19 编辑

来个构思详解:
---------------------------------------------------------------------------
臭不要脸地以自己的帖子为例(掩面):
ascode 应用之 获取输入字符 getc.com
---------------------------------------------------------------------------
在这个 getc.com 中,我最终要实现的功能是:
  1. mov ah,1
  2. int 21
  3. ret
复制代码
其机器码为:
  1. B4 01 CD 21 C3
复制代码
一看就知道除了 21 (asc="!") 之外,其他四个字节都不是可见字符,那肿么办呢?表急,让我静下来想一想...
---------------------------------------------------------------------------
1、
嗯,mov ah,1 用很多命令都能实现,因为 ax 的初始状态是 0000,所以...
比较快的办法是用 xor:
  1. xor ax,3130
  2. xor ax,3030
复制代码
只用 sub 也可以:
  1. sub ax,6060
  2. sub ax,6060
  3. sub ax,3f40
复制代码
可以再无聊点:
  1. inc ax
  2. inc ax
  3. inc ax
  4. ... ;加256次
复制代码
因为最终需求是 ax=0100,所以这个特殊结果也可以取巧用 xor+aaa 实现:
  1. xor al,2a
  2. aaa
复制代码
引申一下,其实最无耻莫过于:
  1. push si
  2. pop ax
复制代码
为什么可以这样,这是因为执行十六位程序的时候,寄存器是有初始状态的,实际是这样的(DX=段寄存器,这几个是会变的,其他均恒定):
  1. AX=0000  BX=0000  CX=00FF  DX=0E1C   SP=FFFE  BP=091E  SI=0100  DI=FFFE
  2. DS=0E1C  ES=0E1C  SS=0E1C  CS=0E1C   IP=0100  NV UP EI PL NZ NA PO NC  TF=0
复制代码
要注意的是,实际执行十六位程序时的寄存器初始状态和在 debug 中表现的不太一样,debug 调试的时候是这样的:
  1. AX=0000  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
  2. DS=13CC  ES=13CC  SS=13CC  CS=13CC  IP=0100   NV UP EI PL NZ NA PO NC
复制代码
这!很!重!要!
如果你的程序不需要操作 cx、dx、sp、bp、si、di 寄存器,那好吧,其实这个知不知道也无所谓了
---------------------------------------------------------------------------
2、
我们已经知道 mov ah,1 不一定要用 mov 实现,那 int 21 和 ret 呢?
貌似没有太直接的办法来代替它们,或者说即使有替代方案,指令也比较长,得不偿失
所以,重点就是怎么在代码段构建出 int 21 和 ret
---------------------------------------------------------------------------
3、
在我的构思中,代码的前半段都是在倒腾寄存器和内存,执行到最后会碰到生成的 int 21 和 ret
为了简化实现过程,在代码末尾附加了三个字节 33 21 3D,这样只需要对 33 和 3D 所在的内存位置做两次 xor [Addr],ff 就能把它变成 CD 21 C3,然后对 0xff 做一次 inc,就能得到梦寐以求的 0x0100
现在实现的关键就在于怎么得到 0xff 和怎么定位内存地址
地址可以通过 [(存储偏移地址的寄存器)+(一个可见字符对应的机器码)] 来定位,所以定位地址的问题就转化成怎么得到偏移地址的问题
至于 0xff...呵呵,这能叫障碍吗?
---------------------------------------------------------------------------
4、
因为 ax 是一定需要改变的,所以我决定把这两个辅助性的数值都放在 ax 寄存器中倒腾
首先取得偏移地址,因为 [(存储偏移地址的寄存器)+(一个可见字符对应的机器码)] 的值得大于 0x100,所以寄存器里的值一定要大于 0x80,考虑到解码部分的长度和可见字符的范围限制,它理想的范围是 0xa0~0xe0 之间,这个用 sub 指令可以轻松做到
将它存入 di 寄存器后,我们再来取得 0xff,通过前文的介绍,你一定知道怎么做
---------------------------------------------------------------------------
5、
万事俱备,只需要用取得的偏移地址+特定的偏移量定位内存地址,对我们希望是 int 21 和 ret 的地方做一次与 0xff 的 xor 运算即可
---------------------------------------------------------------------------
6、
做完运算后,已经得到了 int 21 和 ret,对值为 0xff 的 ax 寄存器做一次 inc 运算,效果等价于 mov ax,0100,表明即将调用的是 1 号功能
然后就是 int 21,调用 21 号中断
再然后是 ret,跳转到 CS:0000 地址处,调用 int 20 结束程序
---------------------------------------------------------------------------
7、
根据需求作一些微调,可避免出现特殊字符 < > " & | 等
---------------------------------------------------------------------------
来看最终成果:
  1. ,RP_4P0E`0Eb@@3!=
复制代码
它在 debug 里反汇编的结果是:
  1. 段地址:偏移地址 机器码     对应的汇编指令
  2. 13CC:0100 2C52          SUB     AL,52
  3. 13CC:0102 50            PUSH    AX
  4. 13CC:0103 5F            POP     DI
  5. 13CC:0104 3450          XOR     AL,50
  6. 13CC:0106 304560        XOR     [DI+60],AL
  7. 13CC:0109 304562        XOR     [DI+62],AL
  8. 13CC:010C 40            INC     AX
  9. 13CC:010D 40            INC     AX
  10. 13CC:010E 3321          XOR     SP,[BX+DI]
  11. 13CC:0110 3D0000        CMP     AX,0000
复制代码
运行一下试试,唔,效果不错,收工回家
---------------------------------------------------------------------------
仔细想了想其实可以简化成这样:
  1. VX0L[Tab字符]..瓮廾
  2. 实际使用时请吧 [Tab字符] 替换成一个 Tab 字符
复制代码
应用了引申4、引申5 和 2 楼列表中的结论和构想,因为含有 ansi 宽字符,所以精简版仅能在 936 代码页下生成正确的脚本
原先的 ascode 长 17 个字节,化简后长度为 11 个字节,而最原始的汇编原型为 5 个字节,看起来是精简到极致了,为什么这么短呢...我就不解释了,请自行研究吧
作者: CrLf    时间: 2014-11-23 01:32

引申1:
除了通过 echo 输出到临时文件,还有一种办法是:
构造一个以 : 开头的 ascode,然后放在脚本头部,然后 copy %0 ascode.com 就行了
为什么能用 :,查 3 楼给出的列表得知它对应的是 cmp 指令,所以其实不限于 :,只要能找出汇编花指令对应的批处理合法语句都能这么做,比如前文提到的 @ECHO  OFF&REM  也可以改造成能够可用的批处理/ascode 混编脚本
作者: CrLf    时间: 2014-11-23 01:36

本帖最后由 CrLf 于 2014-11-23 18:05 编辑

引申2:
ascode 的效率其实不高,16 位程序在 32 位系统里是用 ntvdm.exe 模拟 16 位环境来运行的,它的效率远没有 32 位程序快
到 64 位系统,windows 已经不对 16 位程序提供支持了,所以这个技术貌似是快走到尽头了
事实上,我觉得随着 powershell 的普及,ascode 的存在意义也不是那么大了,虽然 .ps1 脚本默认不能直接运行,但却可以在 cmd 中把 powershell 当外部命令用,这就涵盖了 ascode 能实现的不少功能
作者: CrLf    时间: 2014-11-23 01:53

本帖最后由 CrLf 于 2014-11-23 02:07 编辑

引申3:
人工构造 ascode 比较费劲,需要边写边推算运行时的变化,如果有跳转或者长度超出预期就更复杂了
所以产生了一些算法来自动构造 ascode,个人觉得,最直观的思路应该是类似于加壳/脱壳,将机器码以特定的形式保存成可见字符,使用时再用头部的解释器把它翻译回来,代价是生成的 ascode 必须附加解释器部分,对小程序来说,解释器会比程序原始长度还长很多
我想过去应该还有另一种实现方式:为所有可能的汇编指令做出一个等价的模板,将实际指令逐条处理为模板中的格式,这样得到的结果比较接近于人工构造,但大概只适合小程序,碰到体积原本就不小的程序会膨胀得厉害,相比于加壳/脱壳方案更容易超过 64K 的程序大小限制
---------------------------------------------------------------------------
继续臭不要脸地给出本人拙作作为例子,此例就是加壳/脱壳式的思路:
ascode 的 encode/decode 算法2
还有此贴中 qzwqzw 大神给出的许多外文资料:
http://bbs.bathome.net/redirect. ... 1&fromuid=30406
作者: CrLf    时间: 2014-11-23 02:37

本帖最后由 CrLf 于 2014-11-23 18:05 编辑

引申4:
关于控制字符的特例:
水平制表符(0x09 Tab)、回车符(0x0a Cr)、换行符(0x0d Lf) 对绝大多数数编辑器来说是可见而有实际意义的,所以也可考虑用于 ascode,查表知道它们对应的是一些 or 指令
关于不可见字符的特例:
如果不考虑歪国人的使用环境,不可见字符在 gb2312 编码也不是完全不可见,只要你能组成汉字或者中文标点之类合法的宽字符,同样能把大于 0x7f 的字符用在 ascode 里,这样就能大大简化转换的过程
作者: CrLf    时间: 2014-11-23 02:39

本帖最后由 CrLf 于 2014-11-23 19:31 编辑

引申5:
因为寄存器有初始状态,cx=00ff  bp=091e  si=0100  sp=di=fffe(非Debug环境),所以:
如果要改变的内存地址在 0x120~0x17f 之间,就可以直接用 [si+N] 指向特定位置
0xff 也不需要辗转取得了,cl 初始值就是了,比较高效的办法是用 di 代替 cl,用 xor [Addr],di 一次修改两个相邻字节
---------------------------------------------------------------------
附上 寄存器状态显示.bat,关于实际运行时寄存器初始状态的结论就是用这个得到的
  1. @echo off&setlocal enabledelayedexpansion
  2. set com=vr.com
  3. cd .>!com!
  4. more +19 %0|debug !com!>nul
  5. for /f "tokens=1-14" %%a in ('!com!') do (
  6. set /a "F=0x%%n,CF=F&1,PF=(F>>2)&1,AF=(F>>4)&1,ZF=(F>>6)&1"
  7. set /a "SF=(F>>7)&1,TF=(F>>8)&1,IF=(F>>9)&1,DF=(F>>10)&1,OF=(F>>11)&1"
  8. for %%A in (
  9. CF-CY-NC PF-PE-PO AF-AC-NA ZF-ZR-NZ SF-NG-PL IF-EI-DI DF-DN-UP OF-OV-NV
  10. ) do (
  11. for /f "tokens=1-3 delims=-" %%B in ("%%A") do (
  12. if !%%B!==1 (set %%B=%%C) else set %%B=%%D
  13. )
  14. )
  15. echo AX=%%a  BX=%%b  CX=%%c  DX=%%d   SP=%%e  BP=%%f  SI=%%g  DI=%%h
  16. echo DS=%%i  ES=%%j  SS=%%k  CS=%%l   IP=%%m  !OF! !DF! !IF! !SF! !ZF! !AF! !PF! !CF!  TF=!TF!
  17. )
  18. del !com!>nul&pause&exit/b
  19. rds
  20. 1000
  21. rcs
  22. 1000
  23. eds:100 eb 37 50 b8 0 2 51 b9 10 0 83 e9 4 52 d3 ca
  24. eds:110 81 e2 f 0 80 fa a 72 3 80 c2 7 80 c2 30 cd
  25. eds:120 21 5a 41 e2 e5 59 52 b8 0 2 ba 20 0 cd 21 58
  26. eds:130 5a c3 5a 52 83 ea 7e eb c9 9c 8f 6 0 2 52 89
  27. eds:140 c2 e8 be ff 89 da e8 b9 ff 89 ca e8 b4 ff 5a e8
  28. eds:150 b0 ff 89 e2 e8 ab ff 50 89 ea e8 a5 ff 89 f2 e8
  29. eds:160 a0 ff 89 fa e8 9b ff 8c da e8 96 ff 8c c2 e8 91
  30. eds:170 ff 8c d2 e8 8c ff 8c ca e8 87 ff e8 b4 ff 8b 16
  31. eds:180 0 2 e8 7d ff cd 20
  32. rcx
  33. 87
  34. w
  35. q
  36. 原型:
  37. jmp 139; main;;;;
  38. push ax ;fun
  39. mov ax,200
  40. push cx
  41. mov cx,10
  42. sub cx,4   ;view
  43. push dx
  44. ror dx,cl
  45. and dx,f
  46. cmp dl,a
  47. jb 11c   ;next;;; don't add 7
  48. add dl,7
  49. add dl,30;------
  50. int 21
  51. pop dx
  52. inc cx
  53. loop 10a; view;;;
  54. pop cx
  55. push dx
  56. mov ax,200
  57. mov dx,20
  58. int 21
  59. pop ax
  60. pop dx
  61. ret;;;end fun
  62. pop dx
  63. push dx
  64. sub dx,7e
  65. jmp 102; fun;;;
  66. pushf   ;main
  67. pop [200]
  68. push dx
  69. mov dx,ax
  70. call 102;fun;;;
  71. mov dx,bx
  72. call 102;fun;;;
  73. mov dx,cx
  74. call 102;fun;;;
  75. pop dx
  76. call 102;fun;;;
  77. mov dx,sp
  78. call 102;fun;;;
  79. push ax
  80. mov dx,bp
  81. call 102;fun;;;
  82. mov dx,si
  83. call 102;fun;;;
  84. mov dx,di
  85. call 102;fun;;;
  86. mov dx,ds
  87. call 102;fun;;;
  88. mov dx,es
  89. call 102;fun;;;
  90. mov dx,ss
  91. call 102;fun;;;
  92. mov dx,cs
  93. call 102;fun;;;
  94. call 132;rip
  95. mov dx,[200]
  96. call 102;fun;;;
  97. int 20
复制代码

作者: email10t    时间: 2015-5-7 22:30

来个构思详解:
---------------------------------------------------------------------------
臭不要脸 ...
CrLf 发表于 2014-11-23 00:25



   
只用 sub 也可以:
  1. sub ax,6060
  2. sub ax,6060
  3. sub ax,3e40
复制代码
可以再无聊点:
  1. inc ax
  2. inc ax
  3. inc ax
  4. ... ;加256次
复制代码

作者: CrLf    时间: 2015-5-7 23:20

回复 11# email10t


    脑子没转过来,忘了进制的区别。已修改,感谢指正~
作者: email10t    时间: 2015-5-9 15:16

参考一贴中汇总的帖子内容,其实在 debug 里逐步跟踪就能了解如何具体实现了,只是很累罢了。
其实我也只是 ...
CrLf 发表于 2013-1-21 20:02
  1. ,5Pj!]_jTX(C!!!
复制代码

作者: CrLf    时间: 2015-5-9 23:20

回复 13# email10t


用 debug 跑了一下,看明白了构思,但不懂 DB      6A 是起什么作用的...记得之前跟踪 Herbert Kleebauer 的方案也有多处这样的字节,一直不知道是用来干嘛的

运行后的反汇编结果
  1. SUB     AL,35
  2. PUSH    AX
  3. DB      6A
  4. AND     [DI+5F],BX
  5. DB      6A
  6. PUSH    SP
  7. POP     AX
  8. SUB     [BP+DI+21],AL
  9. INT     21
复制代码

作者: email10t    时间: 2015-5-10 08:00

本帖最后由 email10t 于 2015-5-10 08:07 编辑

回复 14# CrLf

你说的反汇编的结果是:
  1. sub al,35h
  2. push ax
  3. push 21h
  4. pop bp
  5. pop di
  6. push 54h
  7. pop ax
  8. sub [di+bp+21h],al
  9. db "!!"
复制代码

作者: email10t    时间: 2015-5-10 13:56

本帖最后由 email10t 于 2015-5-10 14:01 编辑

回复 3# CrLf
补充:
  1. 60 pusha
  2. 61 popa
  3. 62-63 无
  4. 64 fs:
  5. 65 gs:
  6. 66 push dword *
  7. 67 imul dword *
  8. 68 push word *
  9. 69 imul word *
  10. 6a push byte *
  11. 6b imul byte *
  12. 6c insb
  13. 6d insw
  14. 6e outsb
  15. 6f outsw
复制代码

作者: email10t    时间: 2015-5-10 14:23

参考一贴中汇总的帖子内容,其实在 debug 里逐步跟踪就能了解如何具体实现了,只是很累罢了。
其实我也只是 ...
CrLf 发表于 2013-1-21 20:02

无限循环:
  1. ,/Pj!]_j@X(C!j#X(C"+!
复制代码
反汇编结果是:
  1. sub al,2fh
  2. push ax
  3. push 21h
  4. pop bp
  5. pop di
  6. push 40h
  7. pop ax
  8. sub [di+bp+21h], al
  9. push 23h
  10. pop ax
  11. sub [di+bp+22h], al
  12. db "+!"
复制代码

作者: CrLf    时间: 2015-5-10 19:59

本帖最后由 CrLf 于 2015-5-10 20:13 编辑

回复 16# email10t


感谢补充!
不过 debug 无法识别这一部分指令,但是确实能运行...
应该是 debug 的问题,居然连 pusha 都不支持,用 a 命令试图写入 pusha 也报错
顺便请教下兄台是用什么编写的,能够边写边查看机器码?


回复 17# email10t


也来一个无限循环:
  1. H4P4cP[0@?u2
复制代码
使用 debug 生成:
  1. debug loop.com
  2. rdi
  3. fffe
  4. rsi
  5. 100
  6. a
  7. dec ax
  8. xor al,50
  9. xor al,63
  10. push ax
  11. pop bx
  12. xor [bx+si+3f],al
  13. db 75 32
  14. rcx
  15. c
  16. w
  17. q
复制代码

作者: CrLf    时间: 2015-5-11 04:12

回复 17# email10t


来个 4 字节的,仅能保存为gb2312编码:
  1. AA帻
复制代码
反汇编:
  1. inc cx
  2. inc cx
  3. loopnz 0101h
复制代码
既然都作弊了,索性再来一个 2 字节的:
复制代码
反汇编:
  1. jmp 0100h
复制代码

作者: email10t    时间: 2015-5-17 17:02

Hello World:
  1. RQPUWP]UZV_BBBB5``PY(E.(E3)E5)E:(E>)EFSX3CH<P}pE< ~r%ooQRY2AY0@G uG0EGB?
  2. KO00O0KNX01K91200JMJKN2OLN9J8NNKO0001KNp01K93030JMJKN2OLKN0001_]XYZN9N810
  3. K40NK307KM1L018J4600453L00t04LM10NKO4K407LM21K8004LLM21hello20world2100
复制代码

作者: email10t    时间: 2015-5-17 17:45

来个构思详解:
---------------------------------------------------------------------------
臭不要脸 ...
CrLf 发表于 2014-11-23 00:25


寄存器:
  1.    
  2. AX=0000  BX=0000  CX=00FF  DX=101D   SP=FFFE  BP=091E  SI=0100  DI=FFFE
  3. DS=101D  ES=101D  SS=101D  CS=101D   IP=0100  NV UP EI PL ZR NA PE NC  TF=0
复制代码

作者: CrLf    时间: 2015-5-17 18:26

回复 21# email10t


    ZR 和 PE 是怎么测试得到的?
作者: email10t    时间: 2015-5-17 19:30

本帖最后由 email10t 于 2015-5-18 13:01 编辑

看来 Hello World 程序可能是这样:
  1. 4*7Pj9^]4*7Pj<^]j`X(B (B (B!(B"(B"(B#(B$(B$(B&(B'(B'(B)(B,(B.(B/(B0(B1(B2(B3(B3(B4(B5(B7(B7(B8(B:(BKtnsg}zaJF`E<`td-pKTtg-!x`L-!
  2. Hello, World!`
复制代码
用的是 emu8086 编译的:
  1. org 100h
  2. xor al,"*"
  3. aaa        
  4. push ax
  5. push 3ch
  6. pop si
  7. pop bp
  8. push 60h
  9. pop ax
  10. sub [bp+si+20h], al
  11. sub [bp+si+20h], al
  12. sub [bp+si+21h], al
  13. sub [bp+si+22h], al
  14. sub [bp+si+22h], al
  15. sub [bp+si+23h], al
  16. sub [bp+si+24h], al
  17. sub [bp+si+24h], al
  18. sub [bp+si+26h], al
  19. sub [bp+si+27h], al
  20. sub [bp+si+27h], al
  21. sub [bp+si+29h], al
  22. sub [bp+si+2ch], al
  23. sub [bp+si+2eh], al
  24. sub [bp+si+2fh], al
  25. sub [bp+si+30h], al
  26. sub [bp+si+31h], al
  27. sub [bp+si+32h], al
  28. sub [bp+si+33h], al
  29. sub [bp+si+33h], al
  30. sub [bp+si+34h], al
  31. sub [bp+si+35h], al
  32. sub [bp+si+37h], al
  33. sub [bp+si+37h], al
  34. sub [bp+si+38h], al
  35. sub [bp+si+3ah], al
  36. sub [bp+si+4bh], al
  37. db 74h,6eh,73h,67h,7dh,7ah,61h,4ah,46h,60h,45h,3ch,60h,74h,64h,2dh,70h,4bh,54h,74h,67h,2dh,21h,78h,60h,4ch,2dh,21h,0dh,0ah
  38. db "Hello, World!`"
复制代码

作者: email10t    时间: 2015-5-18 13:15

看来 Hello World 程序可能是这样:用的是 emu8086 编译的:
email10t 发表于 2015-5-17 19:30


有没有更短的 ascii assembly ?
作者: CrLf    时间: 2015-5-18 15:50

本帖最后由 CrLf 于 2015-5-20 01:01 编辑

回复 24# email10t


int 21h 的 9 号中断
利用 bp=91e 可直接令 ah=9
  1. echo ,RP_0Ee0Eg74 42PZUXc!mHello, World!$>问好.com
  2. 问好
复制代码
debug 的格式:
  1. sub al,52
  2. push ax
  3. pop di
  4. xor [di+65h],al
  5. xor [di+67h],al
  6. aaa
  7. xor al,20
  8. xor al,32
  9. push ax
  10. pop dx
  11. push bp
  12. pop ax
  13. db 63 21
  14. db 6d
  15. db 'Hello, World!$'
  16. rcx
  17. 24
  18. w
复制代码
emu8086 的格式:
  1. ORG 100h
  2. SUB AL,52h
  3. PUSH AX
  4. POP DI
  5. XOR [DI+65h],AL
  6. XOR [DI+67h],AL
  7. AAA
  8. XOR AL,20h
  9. XOR AL,32h
  10. PUSH AX
  11. POP DX
  12. PUSH BP
  13. POP AX
  14. DB "c!m"
  15. DB 'Hello, World!$'
复制代码

作者: email10t    时间: 2015-5-19 21:08

本帖最后由 email10t 于 2015-5-19 21:24 编辑

回复 3# CrLf

ascode可用指令大概有这些:
  1. *:  and sub xor cmp j*  daa das aaa  inc dec  push pop pusha popa imul insb insw outsb outsw
复制代码
emu8086 不能直接使用 insb insw outsb outsw,需要 db (define byte)
ascode 不能直接使用 jnle 指令
作者: CrLf    时间: 2015-5-20 01:06

回复 26# email10t


感谢补充
jnle 等同 jg,其实按理也在可见字符范围内,不过 0x7f 确实是特例,给忘了,谢谢提醒
作者: email10t    时间: 2015-7-1 13:23

这类代码过时了
作者: CrLf    时间: 2015-7-1 16:01

回复 28# email10t


    嗯,64位系统不支持,已经退出历史舞台了
作者: email10t    时间: 2015-8-16 10:48

寄存器是有初始状态是这样的:
  1. AX=0000 BX=0000 CX=00FF DX=0DF1 SP=FFFE BP=091E SI=0100 DI=FFFE IP=0100
复制代码

作者: CrLf    时间: 2015-8-16 15:32

回复 30# email10t


    DX=DS=ES=SS=CS,而段寄存器是不固定的
作者: email10t    时间: 2015-8-16 21:58

参考一贴中汇总的帖子内容,其实在 debug 里逐步跟踪就能了解如何具体实现了,只是很累罢了。
其实我也只是 ...
CrLf 发表于 2013-1-21 20:02


还有这个:
  1. P\[581560P\S
复制代码

作者: CrLf    时间: 2015-8-16 23:19

回复 32# email10t


    64 位系统表示没法看,请明示?
作者: sj157250    时间: 2016-7-12 13:07

16楼更正:
  1. 62 BOUND
  2. 63 ARPL Ew,Rw
  3. 66 Operand Size Prefix
  4. 67 Address Size Prefix
复制代码

作者: pcl_test    时间: 2016-7-12 15:37

Printable opcodes in the x86 instruction map
  1. 20/   AND r/m,r (8-bit)      40/@  INC AX      60/`  PUSHA
  2. 21/!  AND r/m,r (16-bit)     41/A  INC CX      61/a  POPA
  3. 22/"  AND r,r/m (8-bit)      42/B  INC DX      62/b  BOUND r,m
  4. 23/#  AND r,r/m (16-bit)     43/C  INC BX      63/c  ARPL r/m,r (16-bit)
  5. 24/$  AND AL,imm             44/D  INC SP      64/d  FS:
  6. 25/%  AND AX,imm             45/E  INC BP      65/e  GS:
  7. 26/&  ES:                    46/F  INC SI      66/f  N/A
  8. 27/'  DAA                    47/G  INC DI      67/g  N/A
  9. 28/(  SUB r/m,r (8-bit)      48/H  DEC AX      68/h  PUSH imm16
  10. 29/)  SUB r/m,r (16-bit)     49/I  DEC CX      69/i  IMUL r,r/m,imm16
  11. 2A/*  SUB r,r/m (8-bit)      4A/J  DEC DX      6A/j  Push imm8
  12. 2B/+  SUB r,r/m (16-bit)     4B/K  DEC BX      6B/k  IMUL r,r/m,imm8
  13. 2C/,  SUB AL,imm8            4C/L  DEC SP      6C/l  INSB
  14. 2D/-  SUB AX,imm16           4D/M  DEC BP      6D/m  INSW
  15. 2E/.  CS:                    4E/N  DEC SI      6E/n  OUTSB
  16. 2F//  DAS                    4F/O  DEC DI      6F/o  OUTSW
  17. 30/0  XOR r/m,r (8-bit)      50/P  PUSH AX     70/p  JO rel8
  18. 31/1  XOR r/m,r (16-bit)     51/Q  PUSH CX     71/q  JNO rel8
  19. 32/2  XOR r,r/m (8-bit)      52/R  PUSH DX     72/r  JC rel8
  20. 33/3  XOR r,r/m (16-bit)     53/S  PUSH BX     73/s  JNC rel8
  21. 34/4  XOR AL,imm             54/T  PUSH SP     74/t  JZ rel8
  22. 35/5  XOR AX,imm             55/U  PUSH BP     75/u  JNZ rel8
  23. 36/6  SS:                    56/V  PUSH SI     76/v  JBE rel8
  24. 37/7  AAA                    57/W  PUSH DI     77/w  JNBE rel8
  25. 38/8  CMP r/m,r (8-bit)      58/X  POP AX      78/x  JS rel8
  26. 39/9  CMP r/m,r (16-bit)     59/Y  POP CX      79/y  JNS rel8
  27. 3A/:  CMP r,r/m (8-bit)      5A/Z  POP DX      7A/z  JP rel8
  28. 3B/;  CMP r,r/m (16-bit)     5B/[  POP BX      7B/{  JNP rel8
  29. 3C/<  CMP AL,imm             5C/\  POP SP      7C/|  JL rel8
  30. 3D/=  CMP AX,imm             5D/]  POP BP      7D/}  JNL rel8
  31. 3E/>  DS:                    5E/^  POP SI      7E/~  JLE rel8
  32. 3F/?  AAS                    5F/_  POP DI
复制代码

作者: sj157250    时间: 2016-7-12 17:16

本帖最后由 sj157250 于 2016-7-12 21:47 编辑

批处理代码:
  1. @echo off
  2. echo jS[SX,SPZ,!P_772W/(]9(]@ !SX5SL !>printc.com
  3. echo 502500PPj`X,~P_0E50E=XZ/!j0X50L/!>p_0x00.com
  4. echo 592500PPj`X,~P_0E50E=XZ/!j0X50L/!>p_0x09.com
  5. echo 582520PPj`X,~P_0E50E=XZ/!j0X50L/!>p_0x0a.com
  6. echo 582550PPj`X,~P_0E50E=XZ/!j0X50L/!>p_0x0d.com
  7. echo 5a25z0PPj`X,~P_0E50E=XZ/!j0X50L/!>p_0x1b.com
  8. echo 5a25A0PPj`X,~P_0E50E=XZ/!j0X50L/!>p_space.com
  9. echo 5a25C0PPj`X,~P_0E50E=XZ/!j0X50L/!>p_quot.com
  10. echo 5a25D0PPj`X,~P_0E50E=XZ/!j0X50L/!>p_0x25.com
  11. echo 5a25G0PPj`X,~P_0E50E=XZ/!j0X50L/!>p_amp.com
  12. echo 5a25I0PPj`X,~P_0E50E=XZ/!j0X50L/!>p_0x28.com
  13. echo 5a25H0PPj`X,~P_0E50E=XZ/!j0X50L/!>p_0x29.com
  14. echo 5A25}0PPj`X,~P_0E50E=XZ/!j0X50L/!>print_lt.com
  15. echo 5C25}0PPj`X,~P_0E50E=XZ/!j0X50L/!>print_gt.com
  16. echo 5a25?0PPj`X,~P_0E50E=XZ/!j0X50L/!>p_caret.com
  17. echo , PP,dPZ]X1F61F?502500-!5Lo51!H-!>p_pipe.com
  18. echo , PP,aPZ]X1F61F?502500-!5Lo51!H-!>p_0x7f.com
  19. echo , PP,`PZ]X1F61F?502500-!5Lo51!H-!>p_0x80.com
  20. echo 503-10PPj`X,~P_0E50E=XZ/!j0X50L/!>p_0xff.com
  21. echo j`_WX4`PYAAAAPP,!P],~(FL(FO(FP(Fd(FmX2E"<@|c,'3APZXP4.74>P]XP2E#<@|c,'$OP">p_0x.com
  22. echo 1XWX502500(F"(F+-!X50m50!">>p_0x.com
  23. printc H >Hello.txt
  24. printc e >>Hello.txt
  25. printc l >>Hello.txt
  26. printc l >>Hello.txt
  27. printc o >>Hello.txt
  28. printc , >>Hello.txt
  29. p_space >>Hello.txt
  30. printc W >>Hello.txt
  31. printc o >>Hello.txt
  32. printc r >>Hello.txt
  33. printc l >>Hello.txt
  34. printc d >>Hello.txt
  35. printc ! >>Hello.txt
  36. p_0x0d >>Hello.txt
  37. p_0x0a >>Hello.txt
  38. type Hello.txt
  39. pause>nul
复制代码

作者: sj157250    时间: 2016-7-13 10:22

  1. @echo off
  2. chcp 437 >nul
  3. echo T_j:X50$P5@@-}VP-0:4~P5l,500P-@?5_$P@-!n50cP51U50@P5!1P]TZ5A8510P(F7(F=-!X5`E-!>~tmp.com
  4. ~tmp.com>~tmp.txt
  5. graftabl 936 >nul
  6. cls
  7. type ~tmp.txt
  8. pause
复制代码

作者: CrLf    时间: 2016-7-14 13:46

补一个链接:https://courses.engr.illinois.edu/ece390/resources/opcodes.html
作者: sj157250    时间: 2016-7-14 17:13

  1. @ECho OFF
  2. :: -!9P^0D00D77'!50M40'!
  3. type %0.bat>~tmp.com
  4. ~tmp.com
  5. del ~tmp.com>nul
复制代码

作者: sj157250    时间: 2016-7-14 17:22

回复 39# sj157250
  1. @ECho OFF
  2. :: P-!9P^0D40D;X5=='!50K40'!
  3. type %0.bat>~tmp.com
  4. ~tmp.com
  5. del ~tmp.com>nul
复制代码

作者: sj157250    时间: 2016-7-15 14:54

  1. @ECho OFF
  2. :: Q_X0EJ0MJ0MK0MORX-__-__-6APZRh01X500PHH,;P5  HHHHHH?P5UMPT]o*^^^4
  3. setlocal enabledelayedexpansion >nul
  4. type %0 >%0.com
  5. %0.com
  6. echo=
  7. pause>nul
  8. goto :eof
  9. :: ??????????????
  10. <子 ASCODE 部分>
复制代码

作者: CrLf    时间: 2016-7-15 19:49

回复 41# sj157250


不妨写明这些程序的作用,供有缘人取用?
另,现在的电脑大多是 64 位环境,想试用也有心无力,ascode 的启发意义大于实用,所以如果愿意写出构造的思路那就有价值啦
作者: sj157250    时间: 2016-7-16 09:51

回复  sj157250


不妨写明这些程序的作用,供有缘人取用?
另,现在的电脑大多是 64 位环境,想试用也 ...
CrLf 发表于 2016-7-15 19:49



    64 位环境需要打开 DOSBox




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2