本帖最后由 CrLf 于 2013-1-21 15:08 编辑
这里给出 encode 代码,拖动写好的 com 到 encode.bat 上进行操作:- @echo off&setlocal enabledelayedexpansion
- set compress=true
- ::设置是否压缩
-
- if "%~1"=="" echo 无文件&pause&exit/b
- set "s1=%~s1"
-
- set list=0123456789JKLMNO
- for %%a in (0 1 2 3 4 5 6 7 8 9 A B C D E F) do (
- set hb=!list:~0x%%a,1!
- for %%b in (0 1 2 3 4 5 6 7 8 9 A B C D E F) do (
- set lb=!list:~0x%%b,1!
- set "hex%%a%%b=!hb!!lb!"
- if %compress%==true (
- if 0x%%a%%b geq 0x50 if 0x%%a%%b leq 0x7e set "hex%%a%%b="
- for %%c in (5E 7C) do if %%a%%b==%%c set "hex%%a%%b=!hb!!lb!"
- )
- )
- )
- ::获取 hex 表
-
- for %%a in ("%~1") do cmd/c exit/b %%~za
- if !errorlevel! gtr 0x3030 (
- echo 文件太长
- pause&exit/b
- )
- ::判断文件长度
-
- set cx=!=exitcode:~-4!
- echo d100l!cx!^&echo q|debug !s1! >"%~n1.bat"
- ::获取文件 hex
-
- set m=0
- (for /f %%a in ('find /n /v ""^<"%~n1.bat"') do (
- set "var="&set /p "var="
- if "!var::=!" neq "!var!" (
- set "var=!var:-= !"
- set "str=!var:~61!"
- set "var=!var:~11,48!"
- for %%b in (!var!) do (
- if defined hex%%b (set "com=!com!!hex%%b!") else set "com=!com!!str:~,1!"
- set "str=!str:~1!"
-
- if "!com:~39!" neq "" (
- set /a m+=1
- set "com!m!=!com!"
- set "com="
- )
- )
- )
- ))<%~n1.bat"
-
- if defined com set /a "m+=1"&set "com!m!=!com!"
-
- (echo @echo off
- echo @(echo RQPUWP]UZV_BBBB5``PY(E1(E6^^^)E8^^^)E=(EA^^^)EI=
- echo echo SX3CP^^^<P}pE^^^< ~r%%%%ooQRY2AY0@G uO0EOB?_]XYZ
- for /l %%a in (1 1 !m!) do echo echo !com%%a!
- echo ^)^>"%~n1.com"
- echo ::这个 bat 是生成 "%~n1.com" 的模板,使用时可以直接复制
- echo pause)>"%~n1.bat"
-
- start notepad "%~n1.bat"
复制代码 需注意的地方:- 生成的 com 前两行是解码部分,不能随意改动
- 支持的加密后的 com 长度上限是 0x6060,也就是 24672 字节(取这个奇怪的数字是因为它既大又不消耗多余指令),超过这一长度将出错,因为解码部分只固定循环 0x6060 次
- 引用 cs:ff 之后的地址时需注意,代码的真实地址是 cs:150(解码部分的长度),对地址进行绝对引用时要注意判断是否需要加 0x60,比如 cs: mov ax,[120] 就应该写成 cs: mov ax,[170],而 jmp、call、loop 等指令使用的是相对跳转,所以不用修改地址
复制代码 当然,解码部分单独运行是没有意义的,还需要用 encode 算法把转换的数据附加到其后。 |