返回列表 发帖

ascode 的一些资料汇编

本帖最后由 CrLf 于 2012-12-23 16:01 编辑

此汇编非彼汇编,它是特殊汇编的资料汇编...唔,越讲越乱
-----------------------------------------------------------------------------------------------------------------
ascode是什么(引用自批处理与其他语言混合编程2):
这类汇编程序的特殊性在于,所有的代码全部分布于ASCII码表的可显示字符范围中,当然这样的程序不是碰巧得到的,而是人为的构造出来的,其中需要用到许多技巧。比如最常见的中断调用代码int 21(CD 21),因为不在ASCII可显示字符范围内,所以用到许多压栈、出栈、增减代码来构造,所以它的代码段是动态变化的。这样的代码被叫做 ASCODE,这样的技术被称作 ASCII Assemble,一门即将消失的技术,可想而知,这样的代码构造起来是困难的,在网上流传的ASCODE只有很少量的是人为构造的,因为已经有成熟的技术可以将任何二进制文件转变为ASCODE,这样的过程叫encode。而ASCODE执行的过程需要decode,合称codec,codec 的算法已知的超过4种,比较有名的应该是Herbert Kleebauer的算法,不过它要求原程序必须有org 170H的类似标记,因为前面的文件头被用来存放decode代码。

后文链接的帖子中如果提到 cn-dos,请自行将链接中的 www.cn-dos.net 替换为备份站点地址 cndos.fam.cx(站点由 qzwqzw 提供)
-----------------------------------------------------------------------------------------------------------------
据说几种编码名称:
uuencoded
base64
binhex
XXencoded
yencoded
能搜就自己搜下吧,反正我是没谷歌到...

-----------------------------------------------------------------------------------------------------------------
cn-dos 全文搜索 ascode 的一些链接(来自 Batcher):
http://cndos.fam.cx/forum/viewth ... mp;highlight=ascode
http://cndos.fam.cx/forum/viewth ... mp;highlight=ascode
http://cndos.fam.cx/forum/viewth ... mp;highlight=ascode
http://cndos.fam.cx/forum/viewth ... mp;highlight=ascode
http://cndos.fam.cx/forum/viewth ... mp;highlight=ascode
http://cndos.fam.cx/forum/viewth ... mp;highlight=ascode
http://cndos.fam.cx/forum/viewth ... mp;highlight=ascode
http://cndos.fam.cx/forum/viewth ... mp;highlight=ascode
http://cndos.fam.cx/forum/viewth ... mp;highlight=ascode
http://cndos.fam.cx/forum/viewth ... mp;highlight=ascode

-----------------------------------------------------------------------------------------------------------------
cn-dos 的搜索结果里整理出的内容:

双句柄同步输出:
echo Bj@jzh`0X-`/PPPPPPa(DE(DM(DO(Dh(Ls(Lu(LX(LeZRR]EEEUYRX2Dx=>tee.com
echo 0DxFP,0Xx.t0P,=XtGsB4o@$?PIyU WwX0GwUY Wv;ovBX2Gv0ExGIuht6>>tee.com
echo @VyI?@xAp~sA`LZNxOq@Kt@FB?sUs`LbLB?tgj`{gjB~0x>>tee.com
tee.com >a.txt 2>b.txtCOPY
根据输入创建bat:
@echo off
echo BATCH_INPUT___hgQX-PPP_XPPP E#HH0E50EG0Ef0Ehs>myinput.com
echo myinput.bat hoAX5@@PZYh@xX5@D3!r/P[WX,b,-PZh>>myinput.com
echo X3!X2ErP,{,{PYX4=0ErWX,j,-PZh@@X3!=set input>>myinput.com
echo Enter your name:
myinput.com
call myinput.bat
echo Hello %input%COPY
将输入的内容输出:
echo hP1X500P[PZBBBfh#b##fXf-V@`$fPf]f3/f1/5++u5x>in.com
set /p passwd=enter your QQ password:<nul
for /f "tokens=*" %%i in ('in.com') do set passwd=%%i
del /f in.com >nul 2>nulCOPY
字节长度计算:
:0hmrX-D@-r0P[h$pX-p#P]3/1/horX-D@-r0P[h?EX-r#P]3/1/h#rX-cA-@0P[1/3/UXtoumCOPY
-----------------------------------------------------------------------------------------------------------------
bathome 全文搜索 ascode 找到的一些帖子,只贴链接代码就不发了。粗筛了一下有所创新的,如有遗漏请跟帖补充:
小型二进制文件ASCII编码器
【挑战】批处理如何创建仅含一个nul字符的文件
[挑战]如何不换行输出以等号或引号开头的行?
屏蔽命令行密码(见附)

附:《屏蔽命令行密码》一贴中 techon 提供的资料:
你可以从下面的连接看到Herbert Kleebauer所参与的3000多个帖子,里面有大量的批处理技术讨论和代码,看来他主要活跃于google group。
http://groups.google.com/groups/ ... xUGDBtnv2zlXxVZTWPs
1

评分人数

    • 老刘1号: 很强大!可惜64位不支持技术 + 1

TOP

回复 2# Demon


    thanks,回头研究下。
    小规模的工程还是可以目测手算的,很累但是很好玩,代码也比较短。稍大的工程恐怕没这个精力,应该用解码段+文本数据段来实现了,有构思,不过貌似早就有了,只是作为一只半英盲实在是谷歌不到

TOP

回复  Demon


    thanks,回头研究下。
    小规模的工程还是可以目测手算的,很累但是很好玩,代码 ...
CrLf 发表于 2012-12-24 00:21


关键在于这种技术的英文名称是什么,ascode或者ascii assemble是否只是以讹传讹的称呼,Google这两个关键词什么都找不到。

TOP

回复 4# Demon


    汗,这个倒是挺蛋疼的,可惜资料少,也许 qzw 会知道吧~

TOP

ASCII Assemble和ASCODE只是圈内人的叫法
并没有得到大范围的公认
该技术的源起于HK和Laura等几位大能的互动
主要活跃时期大概是2000年前后的五六年
相关技术、代码、大能主要散见在Usenet下面几个讨论组中
alt.msdos
alt.msdos.batch
alt.msdos.batch.nt
如果还能访问到Google Group对Usenet的镜像的话
应该还能查到那些讨论的邮件帖子
之前曾经收集过一些代码和技术讨论
不过还是回家找一找再看吧
天的白色影子

TOP

回复 1# CrLf

uuencoded
base64
binhex
XXencoded
yencoded

这些编码大多都不应该算作ASCII Assemble
ASCII Assemble的明确定义我没有找到
但是它有一些显而易见区别与其它技术的特征
最主要的就是ASCODE可以直接保存为.com文件在OS中运行
这与某些二进制转ASCII文本的技术相区别
     
另外为了批处理编写以及网络交流的方便
ASCODE代码中尽量避免利用特殊含义的字符做code
TAB 空格 回车 换行 < > | ‘ ”

另外根据就是早期的文本编辑习惯
批处理代码一般是以80为每行的右边界
所以ASCODE代码一般每行控制在60个字符左右
也因此代码中的回车换行空格等符号也应该可以被“忽略”
天的白色影子

TOP

回复 7# qzwqzw


    为了压缩代码,有三个特殊字符实在避不开,不过好在不多,对于行长度的控制倒是实现了,断行的位置刚好在正中间~不过更新算法貌似多次运行会出错,不知道是什么鬼原因,真的是鬼原因,完全没法调试,认栽了,Fuck...实在解决不了的话,只好把上次的算法改改来用了,那样的话没法压缩长度,恐怕又要到 60h

TOP

Herbert Kleebauer 的 ASCII 汇编教程

How to include binaries into batch files?
========================================

(source code in source.zip)

To include com programs into batch files you have to
write programs which only uses opcodes in the range
0x20 to 0x7e (without  < > | % ^ & " !). Small programs
can be directly coded using the processor opcode table.
Two examples are ech and myinput:

ech.com is similar to the echo command. It writes the
command line after the first " till the penultimate
character to stdout (without an trailing CRLF)

myinput.com assigns a keyboard input to batch variable
@echo off
echo XP,;P_,EP0Ex0Ez0Em3Em-ZBP(Eiu![j@_YQ2M@53#@CI~.8'uxCISZ[SC5.bM!C>ech.com
ech.com "line with <>|^&%">tmp.txt
ech.com "but no CRLF">>tmp.txt
del ech.comCOPY
@echo off
echo BATCH_INPUT___hgQX-PPP_XPPP E#HH0E50EG0Ef0Ehs>myinput.com
echo myinput.bat hoAX5@@PZYh@xX5@D3!r/P[WX,b,-PZh>>myinput.com
echo X3!X2ErP,{,{PYX4=0ErWX,j,-PZh@@X3!=set input>>myinput.com
echo Enter name:
myinput.com
call myinput.bat
del myinput.com
del myinput.bat
echo You entered %input%COPY
For larger programs (more than a few bytes) it is simpler to use
a program to convert a normal com program to an ascii-only program.
The batch below does this job. NOTE: you must assemble your com
program with ORG=0x178 because the first 120 bytes are needed for
the decoding routine which is inserted by the convert program.
Six bits of the original com program are coded in one ascii-byte,
so your program must not exceed 47 kbyte. The decoding routine of
the convert program is (just as MYINPUT and ECH) directly written with
ascii-only opcodes, the rest of the program is a normal com program,
converted by itself to ascii only bytes.
rem - save the lines below as CONVERT.BAT
rem - write a COM program and assemble it with ORG=0x178 (PROG.COM)
rem   (you must not use the standard ORG=0x100 for this com programs!!!!)
rem - enter: CONVERT PROG.COM PROG.BAT
rem - the BATCH file PROG.BAT contains an encoded form of PROG.COM
@echo off
echo Bj@jzh`0X-`/PPPPPPa(DE(DM(DO(Dh(Ls(Lu(LX(LeZRR]EEEUYRX2Dx=>bat.com
echo 0DxFP,0Xx.t0P,=XtGsB4o@$?PIyU WwX0GwUY Wv;ovBX2Gv0ExGIuht6>>bat.com
echo ??wQ@tyM?WxI?@zA=`Lbw?y_y~?_xA[bz?B_L??oAN`_H?e?as?Fx?pkz?>>bat.com
echo B_}A[aIA]b@MCs?A_rVAgr?\gBGpangV_~r?TO?wGJLy?hKxAG@z?G`L?K>>bat.com
echo K?wQO`LRaRPdwA_by??cxA_bL?@O=Et`x?y_z?P_L?@oXZ`SdBW\ngbTiA>>bat.com
echo _Syi?To_gD_lWPOOnSOOOTg`ODgDCDgLCDgNCDg**grKDgtKDgWKDYdKT>>bat.com
echo \QQTDDDTQXTTCqWP}=w@s`aTnbmSILl@gbdTo_n@EwCTokO@mwWDOosPW=>>bat.com
echo kOrFsTnsAP~c?@xHOTV_TPoWvDTvFTV_XPnzuPWAuTuFqSwDoStHFTusgD>>bat.com
echo a}}Oms`DlnbTdILOngbT}o_?`a}SbmsPLlnD??I??~?OBA@TEDCTHGFTKJ>>bat.com
echo ITNMLTQPOTTSRTWVUTZYXTp\[D`_1TcbaTfedTihgTlkjTonmTrqpTutsT>>bat.com
echo xwvT=zyD?}=D????}}??s`aTnbmSILl@gbdTg_nP0>>bat.com
bat.com <%1 >%2
del bat.comCOPY
An example for a program generated with CONVERT is echoo. echoo
is similar to  echo, but you can also include binary characters
by specifying the hex code:
@echo off
echo Bj@jzh`0X-`/PPPPPPa(DE(DM(DO(Dh(Ls(Lu(LX(LeZRR]EEEUYRX2Dx=>echoo.com
echo 0DxFP,0Xx.t0P,=XtGsB4o@$?PIyU WwX0GwUY Wv;ovBX2Gv0ExGIuht6>>echoo.com
echo ?@xAyJHmH@=a?}VjuN?_LEkS?`w`s_{OCIvJDGEHtc{OCIKGMgELCI?GGg>>echoo.com
echo EL?s?WL`LRBcx=k_K?AxVD?fCo?Cd?BLDs0>>echoo.com
echoo This line contains $3c $3e $7c $25 and $24  $0d$0a
echoo           All leading spaces are removed
echoo (to get identical results in DOS/Win9x/NT/2000)$0d$0a
echoo $20       insert a explitcit space ($2420) if you want leading spaces.
del echoo.comCOPY
As an other example you can use this method to generate a hex-to-binary
converter with ascii-only opcodes. This allows you to include any binary
file into a batch file. h2b.com has a string as a parameter. Any line
in stdin, starting with this string, is converted from hex to binary and
written to stdout.
@echo off
if exist %0.bat %0.bat
echo Bj@jzh`0X-`/PPPPPPa(DE(DM(DO(Dh(Ls(Lu(LX(LeZRR]EEEUYRX2Dx=>h2b.com
echo 0DxFP,0Xx.t0P,=XtGsB4o@$?PIyU WwX0GwUY Wv;ovBX2Gv0ExGIuht6>>h2b.com
echo ?@}I{uNWEF~NFAa_Lj@KLtH]~CEvEFIKbAa_wN@SuNS`{ECCttasae~BHM>>h2b.com
echo AcjFnvnHAwrvx[}gIKDw??Frt\gqj~{?s?csIsqo{O_KtBve{Sx{nB{Eu@>>h2b.com
echo fq`tkfk?e@oKCA_?_E@?WxAs?agBwRjnLK?s@w`G`LKLAcyA?@xAsZpk`L>>h2b.com
echo ~KxlqLct@vAc_A_yBJ@xAGZp?o?sBXq`LR@xUrFQt=A_E?B?~rB?~r0>>h2b.com
h2b "::f1" <%0 >bild1.gif
h2b "::f2" <%0 >bild2.gif
h2b "::f3" <%0 >demo.com
del h2b.com
:: hex dump of bild1.gif
::f1 4749463839614b001100a20000140b00fffbf7ff6600fffcfa0000000000
::f1 000000000000002c000000004b0011000003a228badcfe30ca0901bd386b
::f1 66b7ff5f078e64242a419aa2eabaa84cebb2731d2cc39357f1cd0ab306ec
::f1 e503fa5cc8e26cc06c30778d53f0e758d988c6c715f7643ca10ae9902abc
::f1 6db35372faebed86cb4399d23c6f917b32079bdb7c576169687354816702
::f1 7b0a887e5a747f79593f8583897d7c0f6258695b9b479d58893a26704976
::f1 909041a493a61e2725ae25adafb2acb3b52100b8b9babbbcbdbebfc0c1bf
::f1 09003b
:: hex dump of bild2.gif
::f2 47494638396121001000b30000fffdfbff6702ffc39aff9e5effdfcaffef
::f2 e5fff8f4ffffffc0c0c00000000000000000000000000000000000000000
::f2 0021f90401000008002c0000000021001000000463f0c849abbd385f3384
::f2 fe9911041e2811432a1499300e00388c743010d83ce26deddf16110d78d1
::f2 f96a1dd6c485e4518ed0a1406044962451a80aa5751eaadd0a73a8a48c8f
::f2 83f2a480548bd1ee892e0d2a4c05841886793581847d7e1f007882862611
::f2 003b
:: hex dump of an executable
::f3 fcbe3301bf4301b95000b020f3aa89fab91000f3a4bbffffb93c00b409cd
::f3 21b40bcd2108c0750801dae2f0f7dbebe9b44ccd21707265737320616e79
::f3 206b65790d0a24COPY
A further method is, to make a dual executable file. Such a file
is a valid batch program and a valid com program. You can generate
such files with the following batch:
rem - save the lines below as CONVERT.BAT
rem - write a COM program and assemble it with ORG=0x200 (PROG.COM)
rem   (you must not use the standard ORG=0x100 for this com programs!!!!)
rem - enter: CONVERT PROG.COM PROG.BAT
rem - the BATCH file PROG.BAT contains an encoded form of PROG.COM
@echo off
echo Bj@jzh`0X-`/PPPPPPa(DE(DM(DO(Dh(Ls(Lu(LX(LeZRR]EEEUYRX2Dx=>ube.com
echo 0DxFP,0Xx.t0P,=XtGsB4o@$?PIyU WwX0GwUY Wv;ovBX2Gv0ExGIuht6>>ube.com
echo ??wQ@tyM@CxA?@zA=`Lbw??`y~?_xB{_z?B_L??oAN`_H?e?as?Fx?pkz?>>ube.com
echo B_}A{bIB}_@MCs?A_rVAgr?\gBGpangV_~r?TO?wGJxy?xBxAG@z?G`L?K>>ube.com
echo K?wQO`LRaRPdwB?`y??cxB?`L?@O=Et`x??`z?F_L?@oXZ`S?BW\gBDTN_>>ube.com
echo NPLEEDyyI?M_mOhqNT_brD___?gS_S_rhD_rhDa_`P`mhT_xqDlnbTdg_S>>ube.com
echo dc`T_mq@mnCTLsfCyyI?M_mOteNT__m@___?cd_S_shDdgsThe_SsrqTrp>>ube.com
echo _?hk_SrdmTmh_Sgs_S_rhDkheTLmd@yyI?M_mODcNP?iWTtyiD?`oOOgsO>>ube.com
echo OOOT`OOT`CgChCgCjCgCGCgSRKgSTKgSwKgCnK**KgSQQYTDD\TXTDTqW>>ube.com
echo QDOWCTyIL?_my?oWMDEWCTokO@gwWDOssPW=kOrJsTysE@sSsDc?TDHO~S>>ube.com
echo `JxDWUVTVFoS_XTDzUVDAUnTFqWPDoUPHFWTsgtTILk?myy?Lo_??~IOBA>>ube.com
echo @TEDCTHGFTKJITNMLTQPOTTSRTWVUTZYXTp\[D`_1TcbaTfedTihgTlkjT>>ube.com
echo onmTrqpTutsTxwvT=zyD?}=D????IL??myy?my_?0>>ube.com
ube.com <%1 >%2
del ube.comCOPY
As an example, here is a binary executable batch header
(source code: echadd.mac) which supports 2 functions:

e (echo)  and  + (increment)


The increment function increments a decimal number by 1.

example: ube.com +123

will write 124 to stdout (note: no space allowed after +
and after the number)



The echo function is similar to the standard echo command.
The text after the echo command is written to stdout. No
<CR> <LF> is appended. You can output any byte by writing
the hex value ($3c for < or $0d for <CR> ...). $t writes
the current date in the form yymmdd to stdout. After
writing the command line text, echo reads from stdin and
writes to stdout until a <CR> or <EOF> is read. This byte
transfer from stdin to stdout can be modified by subcommands:

l converts all characters to lower case
u converts all characters to upper case
_ converts all spaces to _
. will copy until the first .  (.. until the second . and so on)
: will copy after the first .  (:: after the second . and so on)

The @ must be the first character in the batch file and there must
be no trailing spaces in the first 13 lines.
@EChO OFF
::. NOrisc     This is a binary com header. Don't
::. NOfun      edit the first 13 lines in this file.
::. NO$EXj@jz50!@4(PPPPPPa(D!(D)(D+(DH(LS(LU(L8(L/(LEZRR]EEEUYRX2DXP
::. NX0DXFP,0Xx(t4P,=XtKsF4:tT4U@$?PIyK!WVX0GWUY WV;oVBX2GV0EXGIuht,
::. ?A}I{uNWNN}VINw`{ECCus_ssd{Sj{_?B@spNxH]HTw`}@qr?C}bux{OCEFKNMoS
::. gqx=B@GoBYyE?@xAuwNTECIQtk{SE}CK{B_?CttD_M}B1{BO}CtpB`E?tm{OE}CK
::. {Ba?CtyCaM}B_{B?NMt\ICwd{ECCwtcCs{?QNltPisEHH`LbuuGN@BpozGgbgBYp
::. G?PaKgonOG?w?FgJBYyE?ExA?WgJ?@xAgCj~g?Wqg?Tqj?Fqzgx]dq?Ss?H[Y_`X
::. I{B?{osLRsLS_EuBs~B[IxUCq`{Sy{OOjKvp@{GO{Eq@AvYDu_soB`E?Es~Ft_{O
::. 1oAWaEuBs~B[Ix\Ctm{OE}tMjBaom{nA}LtpBaM?EFtpBaE?]j?m?_gBgXjzB?So
::. ????quuBoDB?FHoGpBBDcB?1~sIGLZp{aB`ksBY`@z?H`L?KINBf?Ecc?_KbxVkV
::. C?Bw_?f{_?Co_?Br0
REM ***************** WIN98 batch***************************
REM This batch file will read a word from keyboard,  convert
REM all filenames with this extention to upper case, replace
REM spaces in the filename by _ and insert the current  date
REM in font of the new filename
if [%1]==[] goto main
_ <nul e $t%1|_ >>__.bat eu_ $0d$0aren %1
goto ende
:main
if exist %0 copy %0 _.com
if exist %0.bat copy %0.bat _.com
_ <nul e enter file extention:
_ >__.bat e set ext=
call __.bat
del  __.bat
LFNFOR on
for %%i in (*.%ext%) do call %0 "%%i"
LFNFOR off
del _.com
echo check __.bat and execute it
REM call __
:endeCOPY
To assemble the source code files, download
ftp://137.193.64.130/pub/assembler/ass486.zip

[email]hk@unibwm.de[/email]

相关附件下载链接: https://pan.baidu.com/s/12FKVNV2spI4UET1MkICjGg?pwd=vi4g
天的白色影子

TOP

Encoding Binary Data into Batch Code

I wrote this up at the beginning of 2002 but did not post it for a few reasons.. the main reason being the BASM dos compiler was replaced with a Windows-based version. Tokiwa disappeared as well, or at least was hiding the last time I looked. ASIC is still around in archives and the Moonrock page works, at least there are a couple tiny-com compilers the modern simple problem-solver can use. Recently I've noticed a renewed interest in how ascii assembler works, and even if my application of it is a bit extreme this document provides a decent overview and links to tools. One usually does not write ascii-assembler by hand if it can possibly be helped, rather encoding/decoding techniques are used to translate existing machine code into batch-legal code. NT-like OS's redefine what is legal, be very careful using some of the raw translaters since they output code NT/XP/etc will not interpret correctly, when machine code is involved the results can be unpredictable, why I adopted a more complicated but compatible approach. If I was smart enough to write a compatible one-step encoder I would but I'm mostly batch and high-level, machine code isn't my thing unless it's for a PIC.

Standard disclaimers, not responsible if you fry your computer using these techniques and programs. Machine code can do just about anything, including horribly crash the computer the errant code is running on. Who knows my code might have a bug, all I can say is it works on my Windows 95 machine, and the output runs under XP. The batch code will likely need adapting to your environment if used, especially CONV2BAT since it is so compiler-specific. If you need to do stuff like this you probably have other specific needs, consider crafting your own solution that best suits your needs, taking code here and elsewhere as examples.

Contents:

Binary to Batch Encoding Techniques
Binary Batch Echo Rules
A Universal Batch-Compatible Encoder and Decoder
Com-file Compilers and Conv2Bat.bat
Conv2Bat.bat file
DecBin assembly source
EncBin assembly source
Using Conv2Bat and Reusing Binary Batch Code
Links to binary batch code and compiler resources
Many times when programming in batch it is necessary to use binary data of one kind or another, be it a helper utility or simply a file without a return at the end. For the purpose of this article, binary means a sequence of bytes where the bytes can take on any value without restriction and can represent a machine code program, a gif file or any other arbitrary file. The important thing is the sequence has to remain exact, there can be no system-created changes or malfunction will likely occur. MsDos Batch is an ascii-based language which can only write files that end in CrLf (Ascii 13, 10), and cannot directly write certain characters that mean other things to the system unless specific steps are taken to ensure syntactic legality. Most of the time batch files are written to use already-existing binary files, however there are times when a single file solution would be better, particularly when distributing a solution for others to use but also to avoid accumulating extra files for trivial purposes.

Just like any programming tool there are advantages and drawbacks. Advantages: Binary-to-batch (Bin-batch) encoding techniques enable batch programmers to recreate any small file as needed. Bin-batch tools let the batch programmer write complex functions in a true HLL (high-level language) then convert it to batch code, rather than relying on unreliable version-specific batch hacks (if the function is even expressible in batch). Carefully constructed bin-batch code can run on all known dos platforms from the earliest MsDos with echo and redirection to Windows XP so long as the underlying app is compatible. Bin-batch text cannot be modified by com-infecting viruses and is safer to redistribute than raw com files, provided of course the files are clean to begin with. Any change is visible and changes the way the encoded ascii "reads" (phrases that randomly appear in a particular routine's encoded text).

Disadvantages: Encoding obscures the original content, and people are fearful of code that cannot be discerned. Depending on the context, bin-batch is no more and arguably less dangerous than simply distributing the binaries with the batch, however in an area where binaries generally are not allowed such as a discussion newsgroup. Posting bin-batch code can get you majorly flamed, in alt.msdos.batch only very small binaries written by known authors are tolerated. Bin-batch code is always a bit slower than merely accessing already-existing binaries, and it adds another layer of possible incompatibility. Creating executable binaries on-the-fly might be against company policy or require specific approval. Some lockdown-style anti-virus (AV) programs prevent the creation of executable code altogether when enabled, other AV programs slow down bin-batches because they have to scan each line of the binary file as it is written to disk. Using a separate decoder greatly reduces scanning overhead by creating the binary in one scanned step (only the decoder has to be scanned line-by-line), or write the com to a file with a non-executable extension then rename before running.

Binary to Batch Encoding Techniques

The old MsDos debug command is probably the most common method of encoding binary data for batch, the command is available on most systems but it is possible the user removed or renamed it, and if booting from floppy you'll have to make sure the debug command is available by putting it on the disk. Debug more than triples the unencoded file size so is best used for very small routines. Numerous debug-encoding utilities are available.

It is possible to write small machine code programs that consist entirely of batch-legal characters and echo it directly to a com file for execution, this method is handy for echoing characters without a CrLf, inputting data and other simple functions that otherwise cannot easily be done in batch. Writing such "ascii assembler" code though is a tedious affair even when one is familiar with assembly, often the results contain more code for patching incompatible bytes than for the task itself but still the utilities rarely exceed a few lines of ascii. Herbert Kleebauer and Laura Fairhead are established experts in this area and have published many useful ascii machine code batch routines on the alt.msdos.batch newsgroup over the years.

Among the most interesting of bin-batch utilities are com-file encoders. After being echoed to disk the com file consists of a decoder consisting entirely of batch-echoable ascii characters followed by an ascii-encoded representation of the original machine code program. When the com runs, the decoder decodes the original code and executes it, if all goes well the original code is not aware of the process. Herbert Kleebauer's Convert.bat program requires that the machine code be assembled at an offset to make room for the decoder. Laura Fairhead's Cm3.com program goes a step further and appends a copy routine, permitting it to encode standard com files.

The method I settled on uses a CM3-encoded decoder that decodes data from one redirected file to another, allowing any small file to be encoded and recreated exactly regardless of its contents. There is more overhead running machine code programs this way but the same decoder can be used multiple times, and the decoding process doesn't produce as much AV scanner activity since only the decoder itself is written line-by-line to a com file. A major reason for going with a separate decoder was to be able to control the encoding process myself, CM3 sometimes produced NT-incompatible output on the 2nd line.

Binary Batch Echo Rules

The code should consist of characters entirely between ascii 32 and 127, if not then nul, eof, bs, tab, cr, lf and probably other characters must be avoided. Must survive editing.
Avoid lines that begin with on[space] or off[space].
Must avoid redirection characters (|<>) unless surrounded by quotes.
Percent characters (%) must be doubled (%%) to result in a single percent in the file.
NT - the characters & and ^ must be avoided.
NT - Avoid [delim][digit] at the end of a line. [delim] is space, semicolon or parenthesis, [digit] is 0-9.
Tricky stuff! Cross-compatibility information can be hard to come by so there may be errors or omissions in the above. Best to keep the encoding method simple as possible to avoid errors with some platforms.

A Universal Batch-Compatible Encoder and Decoder

For my encoding scheme I chose to reduce the range of characters from 256 to 64 starting at ascii 48 ("0") to pack 1.5 bytes per pair of encoded characters. To assure batch compatibility ascii 58 thru 64 (":" to "@") and ascii 94 thru 96 ("^" to "`") are skipped. This encoding scheme doesn't reach the problem ascii 124 pipe character. To create my solution I started with another binary-ascii encoder/decoder pair named zencode/zdecode by Tenie Remmel and replaced the 13-bit (91 position) binary fetch code with by own 12-bit code, along with changes to offset and skip as needed. I further modified the decoder so that it outputs a single RET instruction should the decoded size not match the size recorded at the beginning of the encoded data. Not as good as a checksum but at least provides some protection. The decoder is encoded using CM3, for batch use and distribution the encoder can be encoded by itself. Note that my encoder converts to raw ascii, echo redirection to a file must be added to include within a batch.

Here is a batch containing the decoder which I call "DecBin" and used to decode the encoder I call "EncBin"...
@echo off
set dec=decbin.com
set enc=encbin.com
set tf=encbin.tmp
::---------------------
:: CM3-encoded DecBin decoder...
ECHO:`h}aXP5y`P]4nP_XW(F4(F6(F=(FF)FH(FL(Fe(FR0FTs*}`A?+,>%dec%
ECHO:fkOU):G*@Crv,*t$HU[rlf~#IubfRfXf(V#fj}fX4{PY$@fPfZsZ$:NvN$>>%dec%
ECHO:9AyroNB-)dOKwK0rRkfTbi)ws_~[[q9wE'sqlu1sY*Bsfe=@ziNS1a)88e>>%dec%
ECHO:f9RTL)9Z{3INBD?o6@MDLO{Zz4Q23E-'09NX9@Vz(42A7c8zMS:u$w6k5Q>>%dec%
ECHO:N,h:le)~gF?tutTyxoe5UiIdtn';0rJ1q:{7;lAl']y:yTjZBbOo?QRIdN>>%dec%
ECHO:$Bp@P/nAp_r0*4f'XcF4q3o?$_t5lx$Q-OxSfUNQ__Gd~$Q-Oxgkx=LGHU>>%dec%
ECHO:S)$C6P8#>>%dec%
::---------------------
:: the EncBin encoder, encodes stdin to stdout, encoded by itself...
ECHO:AALIxnCmeRf0\Uf0pWjXYBlxr0MyG02u022nc1Z5Z0r4G2ldMAj[8F34dd>%tf%
ECHO:Z1Z0r4G2ld6Aj[8F34Ed3EmbG02lJpNl0jjjCt9v0407ZvjtS3I0j7rvLv>>%tf%
ECHO:G203l0wUDv20F42eD3ZujTS6fmprbD2e4uwp39gwYdfDfAdng0f1f0ZF2t>>%tf%
ECHO:04bemDCXj0C0LHtA2701ZsG0SFdfW]6630Jf36S6W1f0rJ2fMfQYW1YAoO>>%tf%
ECHO:EAt0y[36S6W1[8LRi3}>>%tf%
::---------------------
:: decode encoder...
%dec% < %tf% > %enc%
if errorlevel 1 echo error decoding binary
if not errorlevel 1 echo Created encoder in %enc%
echo Created decoder in %dec%
del %tf%COPY
To encode a binary manually using encbin.com run: encbin < binary > file then edit file and add "echo " or "echo:" at the beginning and redirection to the desired file at the end of each line. To do this automatically as part of a binary-to-batch batch presents a bit of difficulty, either the symmetry and simplicity of the encoder/decoder pair has to be broken by including echo and file redirection in the encoder output, or the problem can be simply solved using encoded HLL.

Com-file Compilers and Conv2Bat.bat

Several BASIC-like compilers produce com files small enough to encode for batch usage, just about all of them can be found on the Basm page (see links). Each of these has its own particular syntax which has to be memorized, at least where in the doc file the info can be found. For the most part it's like regular basic but expressions must be highly simplified and some of the commands have slightly different syntax. Basm works the best for me but each have strengths and weaknesses... Basm and Moonrock produce assembly source which can be used for hand-tweeking the compiler output. Basm provides easy access to stdin and stdout and produces simple, stable code that should run on any platform that supports dos (I have no info about NT/2000/XP compatibility, I'd guess probably ok). Moonrock worked with everything I wrote with it but the bounce.moo demo crashes and takes down Windows on my machine. Asic is the most complete but the com file often is inflated in size and must be compressed using PkLite or equivalent. Tokiwa does floating point math but I don't know much about it.

The compiler binaries and batch files need to be in path directories so they can be operated by issuing simple dos commands in the directory the source is in. Usually linking batches (@c:\path\prog.exe %1 %2 etc) in a path dir are ok for compilers but some command line parms cannot be passed (specifically asm's ";" no-prompt option) and anything that uses redirection to specify input or output must be available in binary form. On my system I have link batches for asicc.exe, mrc.exe and tbc.com, with basm.exe, asm.exe, freelink.exe and moonrock's mrlink.com in a path directory. In its default configuration Moonrock uses A86 to assemble the output, to use asm unzip mrcasm.cfg from config.zip and rename to mrc.cfg, and make sure everything listed is on the path. Of course it's not necessary to install and learn all of these, to use Basm all you need is Basm, Asm and Freelink.

Conv2bat.bat combines compiling and converting to batch into one step usable from Windows' right-click menu system. Asicc is called to compile asi files, basm/asm/freelink for bas files, Moonrock's mrc for moo files and Tokiwa's tbc for tok files. Notepad or any other text editor can be used to create the source, keep shortcuts to the docs handy. After compiling the source, Conv2bat encodes it into batch form, leaving a .com file and a .bat file with the same base name as the original source file. A batch-commented version of the original source is included in the output batch to help remember what the binary does. If the specified file's extension isn't a supported source file then Conv2Bat encodes it directly to batch, edit the output batch code as needed to use the binary.

All that sounds easy enough... for a real language! Problems... If batch is used as a drag and drop target the current directory is not set to where the file is, rather it must be determined from the passed filename. Essentially the extension must be separated from the rest of the filename but doing anything besides adding strings together is outside the scope of batch. After encoding with EncBin, "ECHO:" and ">>file" (one > on the first line, file is variable) needs to be added to each line to create runnable batch code. To include source code, "::" needs to be inserted before each line. A batch that does all that using only standard commands (if you count debug) is possible, a QBasic script would work, but the former would take quite a bit of hack-style programming, and QBasic isn't installed on every system (and flashes). Binary batch blocks written in Basm easily solved all these problems.

NT compatibility should be reasonably good but NT's find command doesn't return an errorlevel, the part that documents whether or not the com file was compressed with PkLite won't work properly but code output is not affected. Getting away from incompatibilities like this is a major reason for using binary batch (I just hope it doesn't create new incompatibilities), but since this one is minor so I don't think I'll fix unless I get an NT-like system. There may be other incompatibilities I don't know about, all I have is 95 and the Win95Cmd Cmd emulator to test with.

Here is Conv2Bat... (skip to source or more docs)
:: CONV2BAT.BAT - this batch converts HLL source or an
:: existing file (<40K) into equivalent batch code.
:: Required components... (assumed to be on the path)
::  for ASIC (asi): ASICC
::  for BASM (bas): BASM ASM FREELINK
::  for Moonrock (moo): MRC (plus asm/link in mrc.cfg)
::  for Tokiwa (tok): TBC
:: Compresses com with PKLITE, uses Dos6+ FC and FIND to
:: determine if compressed for comments. Disable below.
:: The temp variable must point to a writable directory.
:: This batch is designed to operate by drag-drop, from
:: Windows' right-click menus, or from a dos prompt.
:: Usage: CONV2BAT [path\]filename.ext
:: If extension is asi bas moo or tok then produces
:: filename.bat containing batch-encoded binary with
:: attached source, in addition to compiler output.
:: If ext not supported then encodes binary to batch.
:: Tested in Win95, should be dos and NT-tolerent except
:: for compression test (see comments) but maybe more.
:: This is free software and comes with no guarantee,
:: test thoroughly before distributing the output code.
:: Last major mod 12/08/01, last mod 1/03/02
:: (C) Copyright 2002 Terry Newton
:: EncBin encoder, DecBin decoder and Basm helpers
:: are public domain, use as you wish.
@echo off
if .%1==.Shell goto %1
if not .%1==. if exist %1 goto fileexists
echo  Compiles HLL source and converts to batch
echo  Usage: CONV2BAT [path\]filename.ext
echo  Compiles .asi .bas .moo and .tok files
echo  encodes other types directly to batch
goto end
:fileexists
:: shell with lots of environment space
%comspec% /e:30000 /c %0 Shell %1
goto end
:Shell
::**** options, edit as needed...
:: usepklite=yes to compress with pklite
set usepklite=yes
:: usetempdir=yes to use temp dir in output code
set usetempdir=no
:: decname=filename used for decoder
set decname=_d.com
:: tempname=filename used for temp file
set tempname=_t.tmp
:: extension to output batch code to
set outputext=bat
:: callconv2cfg=yes to put variables in conv2cfg.bat
set callconv2cfg=no
:: temp filenames...
set dec=%temp%.\_decbin.com
set enc=%temp%.\_encbin.com
set file2bat=%temp%.\_2bat.com
set cmntsrc=%temp%.\_cmntsrc.com
set sepname=%temp%.\_sepname.com
set replace=%temp%.\_replace.com
set tf=%temp%.\_tf.tmp
set tf1=%temp%.\_tf1.tmp
set tf2=%temp%.\_tf2.tmp
:: override variables if configured...
if .%callconv2cfg%==.yes call conv2cfg.bat
:: double check...
set xyz=0123456789012345678901234567890123456789
if not .%xyz%==.0123456789012345678901234567890123456789 goto end
set xyz=
echo.
echo  **** CONV2BAT **** 12/8/01 WTN
echo  Checking file support...
::-----------------------
:: CM3-encoded DecBin decoder...
ECHO:`h}aXP5y`P]4nP_XW(F4(F6(F=(FF)FH(FL(Fe(FR0FTs*}`A?+,>%dec%
ECHO:fkOU):G*@Crv,*t$HU[rlf~#IubfRfXf(V#fj}fX4{PY$@fPfZsZ$:NvN$>>%dec%
ECHO:9AyroNB-)dOKwK0rRkfTbi)ws_~[[q9wE'sqlu1sY*Bsfe=@ziNS1a)88e>>%dec%
ECHO:f9RTL)9Z{3INBD?o6@MDLO{Zz4Q23E-'09NX9@Vz(42A7c8zMS:u$w6k5Q>>%dec%
ECHO:N,h:le)~gF?tutTyxoe5UiIdtn';0rJ1q:{7;lAl']y:yTjZBbOo?QRIdN>>%dec%
ECHO:$Bp@P/nAp_r0*4f'XcF4q3o?$_t5lx$Q-OxSfUNQ__Gd~$Q-Oxgkx=LGHU>>%dec%
ECHO:S)$C6P8#>>%dec%
::---- EncBin-encoded binary ----
:: sepname.com made with BASM ASM FREELINK
ECHO:AEPPr64U2y00tD61O0AAj7CDXn28A5S5D7JeRkl5Ll00xG47uvgmv5gl[5>%tf%
ECHO:gGC0v]U[2uY7213301EBu1Je13dnJDrX5OIZO5QZO5ibr1Vbj3AxS5Ayv6>>%tf%
ECHO:Zb02ibf3Axv6Rbf2RbC2Ayv6Jbf3abb3Axv62yK6ebr12rK6ZbC2ib42Ay>>%tf%
ECHO:v6ab[3Axv6Eyj5Rb42Dn3e0J]xN53b8l3b6l3bB\2jG0gC7DB7n6j50037>>%tf%
ECHO:v6j5000mF0cdr5ilW6tfC106Ld2ZNH37C6n5003yC6n5EXn5Ou3Hr5S3Fe>>%tf%
ECHO:IGebC3Axv6EXn56u00qbC3ybb1EyG7qb83ExG7Myn5ebb1Dn3e07]XNJ2Z>>%tf%
ECHO:ND2xT32yNN3b6M1nf3r76GeJC5eFf5thpXj5Ou3Fv5S3Ve2GR73F0500Rb>>%tf%
ECHO:r2]xn5Iy[7Vb81ebn2Axv6Myr7ib41ubj2hxn5QyC8yb01t3FF451yf3s6>>%tf%
ECHO:EGF0O33FK53yFyeTW5tfv2vpNT1bRl3b933b4Z2yV\3bAX0mF006NH0ev6>>%tf%
ECHO:j5pZn5abW2RyFTW5RlW6rrW2r0v1fpW8sxC2WxND01Dy3e1I]XND2ZNT3b>>%tf%
ECHO:9Z3ynpn59bv6ebv1ebn0Iy[7ZbK20mlZLd2xV\3b2N03b6O5pZn50mj3n6>>%tf%
ECHO:n5Oe3DC5eTW5rhv2vpNT1bV\3b7T3b2\2yV\3b8Z1bNV3b8s1bUK3b8m1b>>%tf%
ECHO:LR3b8g1bNd3b8a1bV\3b8X1bLR3b8R1bNo3b8L1bWp3b8F1bLR3b892n9C>>%tf%
ECHO:F07DAn83Fy3D4me0Z23xlZLI2Au6y0IZK5i3WMLI3x7AcKb5Zjuxlnn2jG>>%tf%
ECHO:m3xfdd30coy3PHLNtBvla0iymyylUhyHg9Z1sVLP73LNPMLNXUuXiyZOXU>>%tf%
ECHO:uRiyZ8s1LVf3yvRmA[DPlxPG2yNy3byRy3TGLMmvdhHo0AN0VrwULOi3Zr>>%tf%
ECHO:6sK0ivZqlfD1Pl0vwQS20ftdBYy3ebaygGZ8]3v0gxEBOUK5IXK5tBDIr5>>%tf%
ECHO:46w8I33y1yC2Fy2tK0Bqr37rqa2r2j2ElnnFjGSv1nW5f0trZ0Jvb]p857>>%tf%
ECHO:ZYv7WVK186K5y3hXW6s3uyhXW6ryr0gGv6hXW6rnuyhXW6r1C0lyQX3bva>>%tf%
ECHO:xxQX2yPG3bvUxxPG3bvWxyPG2BF83rpA603u9yCBF0M819DFZsn0Vhy3hX>>%tf%
ECHO:W6uruxhXC6F9l0CWTo16D1ZsLHVn6sK02yK6Fvv]E[m786K5013yG6K5t3>>%tf%
ECHO:DKb55ov4vELK2tLO2nn9jXtB5Ib5ZJexlBGUK5EAyxFEFRAn3DCGkLlBtB>>%tf%
ECHO:Hp2yPG2BPE3vRmA[0ml8n5N2041LlBt3Bf0ma0X6ixXpW4t8ix9606I9s6>>%tf%
ECHO:vw001wW6f1[0X6yxgGO6j5f0Xpv4gGC61puxIs1H0esEyvRmA[0ml8f5Z\>>%tf%
ECHO:9Tj4v0iyC5F0M933xxv5mbFxF3LGmbuyyvgGW6K3ujHPRmA[N600N3MBif>>%tf%
ECHO:XpW4r\ixZ86u00QBK42nJDnXN202014000070DGA8D0A07000000000000>>%tf%
ECHO:0000000000000000000000000000000000000000000000000000000000>>%tf%
ECHO:0000000000000000000000000000000000000000000000000000000000>>%tf%
ECHO:00000000whOW5jPl1g0000000000j0K00h000000001mH\SW1]TXXnOwC0>>%tf%
ECHO:T\1n9]5YPmo\C0LmPnOWP\HrSwn0}>>%tf%
:: BASM source...
:: rem separate specified name into fpath,fbase,fext
:: rem outputs sets to stdout
:: $com
:: a$=command$:a$=trim$(a$):a$=lcase$(a$)
:: if a$="" then
::  print "no parm":end
:: endif
:: rem loop through string, mark last \ and .
:: slash=0:dot=0:ilen=len(a$)
:: for i=1 to ilen
::  c$=mid$(a$,i,1):if c$="\" then slash=i
::  if c$="." then dot=i
:: next i
:: rem not an extension if \ after .
:: if slash>dot then dot=0
:: fpath$="":fbase$=a$:fext$=""
:: if dot>1 then
::  d=dot-1:fbase$=left$(a$,d)
::  d=ilen-dot:fext$=right$(a$,d)
:: endif
:: if slash>1 then
::  rem includes trailing \
::  d=slash:fpath$=left$(a$,d)
::  d=len(fbase$):d=d-slash
::  fbase$=right$(fbase$,d)
:: endif
:: output "set fpath=";fpath$
:: output "set fbase=";fbase$
:: output "set fext=";fext$
::-------------------------------
:: decode and use _sepname.com to parse input (in %2)
%dec% < %tf% > %sepname%
if errorlevel 1 goto binerror
%sepname% %2 > %temp%.\_sep_tmp.bat
call %temp%.\_sep_tmp.bat
del %temp%.\_sep_tmp.bat
if .%fpath%==. goto incurrent
:: change to source directory
%fpath%
cd %fpath%
:incurrent
if exist %fbase%.%fext% goto curdirok
echo  Could not change to directory
goto cleanup
:curdirok
:: *******
:: ******* compiler support, edit as needed
:: *******
if .%fext%==.asi goto asifile
if .%fext%==.bas goto basfile
if .%fext%==.moo goto moofile
if .%fext%==.tok goto tokfile
echo  Unknown filetype, encoding as-is
set compname=
set madewith=????
set binfile=%fbase%.%fext%
goto conv2batch
:asifile
set compname=ASIC
set madewith=ASICC
if exist %fbase%.com del %fbase%.com
call asicc %fbase%.asi C
goto checkcom
:basfile
set compname=BASM
set madewith=BASM ASM FREELINK
if exist %fbase%.com del %fbase%.com
call basm %fbase%.bas
if exist %fbase%.asm call asm %fbase%.asm ;
if exist %fbase%.obj call freelink /c %fbase%.obj
goto checkcom
:moofile
set compname=Moonrock
set madewith=MRC ASM MRLINK
if exist %fbase%.com del %fbase%.com
call mrc %fbase%.moo
goto checkcom
:tokfile
set compname=Tokiwa
set madewith=TBC
if exist %fbase%.com del %fbase%.com
call tbc /c %fbase%.tok
goto checkcom
:: ******* end compiler commands
:checkcom
set binfile=%fbase%.com
if exist %binfile% goto comexists
echo.
echo  =======================================
echo    Compile failed, debug and try again
echo  =======================================
echo.
goto cleanup
:comexists
if exist %fbase%.obj del %fbase%.obj
:: try to pklite it (if option enabled)
if not .%usepklite%==.yes goto conv2batch
copy %binfile% %tf1% >nul
call pklite %binfile%
fc /b %binfile% %tf1% > %tf2%
find "00" < %tf2% > nul
::reset var for docs if not changed by pklite...
::note--not NT compatible here, PkLite status won't
::be properly indicated in the output batch comments
if errorlevel 1 set usepklite=no
del %tf1%
del %tf2%
:conv2batch
echo.
echo  Converting to batch code...
::---------------------
:: the EncBin encoder, encodes stdin to stdout, encoded by itself...
ECHO:AALIxnCmeRf0\Uf0pWjXYBlxr0MyG02u022nc1Z5Z0r4G2ldMAj[8F34dd>%tf%
ECHO:Z1Z0r4G2ld6Aj[8F34Ed3EmbG02lJpNl0jjjCt9v0407ZvjtS3I0j7rvLv>>%tf%
ECHO:G203l0wUDv20F42eD3ZujTS6fmprbD2e4uwp39gwYdfDfAdng0f1f0ZF2t>>%tf%
ECHO:04bemDCXj0C0LHtA2701ZsG0SFdfW]6630Jf36S6W1f0rJ2fMfQYW1YAoO>>%tf%
ECHO:EAt0y[36S6W1[8LRi3}>>%tf%
::---------------------
:: decode encoder...
%dec% < %tf% > %enc%
if errorlevel 1 goto binerror
::---- EncBin-encoded binary ----
:: 2bat.com made with BASM ASM FREELINK
ECHO:AFDJr64U2y00tD61O0AAj7CDXn28p5j5D7JeRkl5ND00xG47uviEv5iD[5>%tf%
ECHO:gGC0v]U[2ues213301EBu1Je13dnJDrX5OhZf5pZf5JbC2qb04pxj56yb8>>%tf%
ECHO:ybC27b046xb8ubv2qbO26yb8ebv3ybr36xb8qbf2ibK26yb8Zbr36xb8ty>>%tf%
ECHO:46RbK2Do3c7j0mF0e5v5hXr8fYW6sQC206N52ZO[23Gx86v0S37cn13bf3>>%tf%
ECHO:RyC[W6QXW8s7W3rOv2fPW9t\W3tQr3fPW9sbW2r6v2fPW9tJC3F0MZj56x>>%tf%
ECHO:b8Fbj1O335C5b]C6F0O30]f686O[2ZO]3bDc3yOp865bb8Zb437bn16y[9>>%tf%
ECHO:ubK30mlZN52y]H2xOY3b7U03K6j5IZ86t3C[061y[3sLW1rnv3vpO[1b]H>>%tf%
ECHO:3bBB3b6S2yb93bCc3bCU2xb93b7f3b6A2yb93bCN0mF0e5r5hHW9s7C106>>%tf%
ECHO:N52ZO]0mF006O]0eG686QZ86qbr2RyC]W6QHW9tSW2sLv1hHW9uYb2fPf9>>%tf%
ECHO:fbW6ubC2WxMs00Dn3c3\2tb92rOd3bB]23[xf5G0S3Bcn0R70f0600ibb2>>%tf%
ECHO:tx866yWAqbn0t3Cf061n[3tYO0j6YX006GbbW6tkr1fsv6hXW8tx40e3C5>>%tf%
ECHO:bfC6WxOf00Dn3e1u]xOj3b2j2B78bdf6ZO2tC62nJDWXuer0hXW8tPf0Z8>>%tf%
ECHO:dX86YBptYX2no0jXJbn06xWABbW0YBlXOd2BeOh1GAg07DBb2w2x]H3b1e>>%tf%
ECHO:2B78bdf6ZO6t[92nJDWXt]40bdf6ZOAs00xtb52nJDWXtKW0r2r2fpv6h1>>%tf%
ECHO:WArnf0r4hGr4]GsEiyWUOd3b7r2BWU867bv1lnGlq0jXEn0lqyjG0mlAu2>>%tf%
ECHO:y0]Zb5QAmxF0deC5mvdfbAN0Vt73LMgNZx0llsyyyvuleqaHIBy1LUDPkH>>%tf%
ECHO:PNLMsNNbyXxBuONbyRxB78HUDV3uFvv]][N36xf7]yC7ibqy33LNkMxfMh>>%tf%
ECHO:S40AkourLVDOkmC3dsW5y3XLtciyZOgMZq7bey2BoUtBsBVvMBmodBBAxh>>%tf%
ECHO:ko6BiHZBRmcnCB3sfevuVJVaee2GfexBi7Keq3N30mkRDTlyWc3bwXxxWc>>%tf%
ECHO:2yUk3bwOxxUk3bwQxyUk2BF83rpA603u9yCBF0M819DFZsn0Vhy3fcW8rl>>%tf%
ECHO:uyfcC8F9l0CWTo16D1ZsLrVnYsS06yf7Fvv]E[kWYBps3y2tOs2nnyjXol>>%tf%
ECHO:KBJ0TPDGLI8ULV2BpxMi2u022BihJvMBxfdBmlMhSQ6BpBFBx]gn03isBu>>%tf%
ECHO:Cuoqiar8hGBuXFye02asxBq6070VgQLOXl63B70eVtKeV7yOhPZ867pr81>>%tf%
ECHO:JDWXNe0Fabuuy7C6j5012BRQj740R3gLZfQBS46yf7tBG6Fvv]E[F0M81T>>%tf%
ECHO:J200gLZfl3r20ml9s6xBHp3bssveP610Q9Jx0w00Pw2r0129s6xyUk3605>>%tf%
ECHO:2BHp2yUk03spwEYsS0reJxFvv]E[F0M82Bq\N2042ySs0ma0W5u3fsW7rg>>%tf%
ECHO:FxlnnxjXabVxF3KmF0e3G5fw7DBbsewRU9331IKma9WEN32nnvjXZbNx\R>>%tf%
ECHO:W7YBpnnxjXmbJx1Qf1pnFDWXs2Fxj14000070DGA8D0A07000000000000>>%tf%
ECHO:0000000000000000000000000000000000000000000000000000000000>>%tf%
ECHO:0000000000000000000000000000000000000000000000000000000000>>%tf%
ECHO:00000000000000000W000000000000000x15X3HF0t0x0x0g}>>%tf%
:: BASM source...
:: '2bat infile outfile tmpfile
:: 'reads infile, surrounds each line with
:: '"ECHO:" and ">>tmpfile" (one > 1st line)
:: 'and outputs results to outfile
:: $com
:: $string 120
:: a$=command$:a$=ltrim$(a$):a$=rtrim$(a$)
:: if a$<>"" then
::  b=instr(a$," ")
::  if b>0 then
::   infile$=left$(a$,b)
::   infile$=rtrim$(infile$)
::   c=len(a$):c=c-b
::   tmpfile$=right$(a$,c)
::   b=instr(tmpfile$," ")
::   if b>0 then
::    outfile$=left$(tmpfile$,b)
::    outfile$=rtrim$(outfile$)
::    c=len(tmpfile$):c=c-b
::    tmpfile$=right$(tmpfile$,c)
::    open infile$ for input as 1
::    if err=0 then
::     open outfile$ for output as 2
::     if err=0 then
::      done=0:b$=">"
::      while done=0
::       line input #1,a$:done=eof
::       if done=0 then
::        print #2,"ECHO:",a$,b$,tmpfile$
::        b$=">>"
::       end if
::      wend
::      close 2
::      close 1
::     end if
::    end if
::   end if
::  end if
:: end if
::-------------------------------
:: decode 2bat utility...
%dec% < %tf% > %file2bat%
if errorlevel 1 goto binerror
::---- EncBin-encoded binary ----
:: cmntsrc.com made with BASM ASM FREELINK
ECHO:ADLNr64U2y00tD61O0AAj7CDXn28h5G4D7JeRkl5HB00xG47uvgCv4gB[4>%tf%
ECHO:gGC0v]U[2uS1213301EBu1Je13dnJDrX5O]ZC4hZC4ybb0Zb[2hxG42yf6>>%tf%
ECHO:mbj0mbW22xf6ebO1ebv02yf6NbW22xf6ly[4Nbv0Dn3e0J]xIU3b413b2H>>%tf%
ECHO:3b8j2jG0gC7DAtQj2uI]3b9e2XGq2ZIb23Wxb4v0S3Fe6Gdxb4Rbn0RbO0>>%tf%
ECHO:Nb022j2noCjXR62j062GQXb4VbS1pxf42yf6ebK06XG4YZb4t3Eb041nf3>>%tf%
ECHO:rLYGQsW4riW2QjW6rcW2OjW4rZf2u7tB6]W4r1G2gC0lmDGXf3vlyDCGF0>>%tf%
ECHO:AAmxF0bab4Z63xlZGc33QB4ar4yA]X842AyxJEf23D73mvdd0AkoFtkHTM>>%tf%
ECHO:MBBxF0xsyyBvxh7qo96BkV\UN3THLMTMLU7buyYBoUibqyYBk1wUK3muym>>%tf%
ECHO:G]cPu3fEv6hwW5uRFykGPNNvtfcob430XowUXVN3Dm2ZGq3rZ3td3yMBF8>>%tf%
ECHO:Zsr0SutB4e44bcf4WxGa0UW6HFx3v09y0meygGS0yYW3yHZaf0tjZ0xn3D>>%tf%
ECHO:jGC7Ln2rW0hEm0x[W]WT97urv75OO10aC4lyPV3bwJxxPV3b0y2xOE2yPV>>%tf%
ECHO:3bw4xxPV3b0133xyK6VbFyxxK6ty06ubBytx063bFyty06YBj3erWTh0vW>>%tf%
ECHO:gy0mZ0W5w9I33s1wFhlyPV3bv8xxPV0m39WvKWS756I37sLoangHv0fEj6>>%tf%
ECHO:ymG]e3gWZOxsv0ptf4xnFD8XTT0Bkn1PLJsI5IgVZGpx84Au00tBsBivZo>>%tf%
ECHO:hfZAulcofQZHhBmmI]SB[3veiuFJTque08[eyuJrBe2GisZVV600bVLR9O>>%tf%
ECHO:SOU3j2bewNSemqaO]BV8ZH6r127D9Oye2G7bqxR7114400dBq6071XV3j6>>%tf%
ECHO:Ga01v0v6Gc23[x84KQS4uy0cb4fgG4f97DABSU84EAqxiAWUGc2AumyEfm>>%tf%
ECHO:pnn2jGy3hwC5F0M933pxf5ybBxJ3fx7DBbsuy3DJF06ZG4pnFDWXsgixM9>>%tf%
ECHO:C7kLlBtBHp3brKxBi8f1f0XMG4g07D9TB2000101S000bD0[bD00070000>>%tf%
ECHO:0000000000000000000000000000000000000000000000000000000000>>%tf%
ECHO:0000000000000000000000000000000000000000000000000000000000>>%tf%
ECHO:000000000000000000001h1i9j9XTg0000001]kcP\rWPi1n9]LiTh1[0t>>%tf%
ECHO:0t80jt}>>%tf%
:: BASM source...
:: rem open file specified on command line and write
:: rem to stdout with ":: " prefixed to each line
:: $com
:: a$=command$:a$=trim$(a$)
:: if a$="" then
::  print "no parm":end
:: endif
:: open a$ for input as 1:e=err
:: if e>0 then
::  print "file not found":end
:: endif
:: fileloop:
:: line input #1,a$:e=eof
:: if e=0 then
::  output ":: ";a$:goto fileloop:
:: endif
:: close 1
::-------------------------------
:: decode cmntsrc utility...
%dec% < %tf% > %cmntsrc%
if errorlevel 1 goto binerror
::---- EncBin-encoded binary ----
:: replace.com made with BASM ASM FREELINK
ECHO:AGINr64U2y00tD61O0AAj7CDXn28Q587D7JeRkl5S]00xG47uvfav7f][7>%tf%
ECHO:gGC0v]U[2uMDA13301EBu1Je13dnJDrX5OYZ47dZ47Fbv2ibO5pyW9dr00>>%tf%
ECHO:M90maRXTW1s3v3hDWJs[W5sIv5hDW9fD[0W5fmp95T3bCd2yMD7bLB3bKs>>%tf%
ECHO:2y]D2r0Y29C5FRp9K17b43pyWNBbC53b85Qx87pyWPNbj2Jb45pxWPabK4>>%tf%
ECHO:Fbv2pyWPJb45Bb05pxWPZb447br2pyWPBb053bv45d1b]D7bI93bBD2yhD>>%tf%
ECHO:7bJh2xhD6yUD7bB81of3r4]Gr7C2F0tZ47pxWPabS2O30UC7cqv7vETq3b>>%tf%
ECHO:Io3ySpS7obWPJbO43b[2pyWP7bf40mlZSU2y]D6xUD7bC]03r647]ZS7t3>>%tf%
ECHO:Ds871vf3r1xGvETs3bHv3y[pS7obWPFb44VbK2pyWTZbS4Q31s870mF0bU>>%tf%
ECHO:r7hDWPrFC206SU2ZTq0mF006Tq0e[6S7hZS7BbG4RyDuW7QDWPukW3rTv2>>%tf%
ECHO:hDWVrxW4rfr4hDWVskW3rBv2hDWVrfW4rQb4O1obWVFbf3Vbv1pyWRZb44>>%tf%
ECHO:pxWRpyWNBbv1Do3e04ac4k3bFo1dW1QDWVt]W3uIv1hDWRumr3hDvRhDWN>>%tf%
ECHO:uDK1S3Je2Gmc010mlZSU2xxD7b5x03r647UZS7t3Dq871vf3r4]GugC0Wx>>%tf%
ECHO:Tq02Dy3e0raySES7Fbb3RyDqW7QDWVsIW3sxv1hDWVtVv3vETq3bE93ySp>>%tf%
ECHO:S7obWV3b83JbO1pyWVNbW3qe2G3bS3pxS7pyWVNb41JbO3xxS7pyWXab01>>%tf%
ECHO:R7210700BbK3ubS3JbC1pyWZNbK3pxWZEyW7yb81Dn3e04ae1S]xEDAyMD>>%tf%
ECHO:7b4U1nf3r3hGuGpxWZpyWJub01Dn3e0Oab1V3bCH2xU52y6DBb2p3746W7>>%tf%
ECHO:003e6eWxU100j2S3ee6GBbv2pxWXJbv2pxWZubr2pyWXybr2Ry21f7t5t3>>%tf%
ECHO:E1071yf3r4YGrO00f0lnJDrXh7W7tHW1sQW0rc02f0lnJDrXhDvThDWBsQ>>%tf%
ECHO:r0hDvVhDWDsHr0hDvXhDWFs8W0tPr0hDv7hDWXrvW0QDWXtUW2OFW7tOC2>>%tf%
ECHO:ln9CF07DAn83Fy3D4me0Z23xlZS62Au6y0YZ07i3WMS63x7Ab8b7Zjuxln>>%tf%
ECHO:n2jGm3xfdd30coy3PHLNtBvla0iymyylUhyHg9Z1sVLP73LNPMLNXUuXiy>>%tf%
ECHO:ZOXUuRiyZ8s1LVf3yvRmA[DPlx]D2yUD3byRy3TGLMmvdhHo0AN0VrwULO>>%tf%
ECHO:N3MBFfZfv6hDOHj5v0hDO7j5r0hDWFtSayX6uxhDWBtJayX6FvF0Q9JtRy>>%tf%
ECHO:JtQBJtOuJxXyMxxD2y]D03cpwEtBJvFvv]E[F0M82x]D2y6D7bwQxx6D6y>>%tf%
ECHO:hD3bxLworLhDvDhDW7s[iyX67v16ytwEitrPtGhDvFhDC91putIs013vRm>>%tf%
ECHO:A[0ml8W5sSiytTMBsTN3NbvWxBROMBZqrOiyZGgUZhkBwNMBxfdBmlMhSS>>%tf%
ECHO:6BpBFBx]gn03isBuCuoqiarAhGBuUBkRCekTF3F0oRN3FbuxgGZ8]3v0gx>>%tf%
ECHO:EBbU07YX07tBC6r746w8I33y1yC2Fy2tK0Bqr37rqa2r2j2ElnnFjGSv1n>>%tf%
ECHO:W5f0trZ0Jvb]p857ZYv7WVK1O607y3hDWBtCuxhDvBhDW9t3uxhDW9t5yx>>%tf%
ECHO:hDf9Z8W3xA0TZuvWSB0ml8[5HF]3v0swu3pyWBqbNxpxWB[ml00v9oO8H1>>%tf%
ECHO:]1v0K2Vm2s02pyW9Fvv]E[m7O607013yW607t3C8b75ov4vES82tSC2nn9>>%tf%
ECHO:jXtB46b7ZJexlBWU07EAyxFEFRAn3DCGkLlBtBHp2y]D2BPE3vRmA[0ml8>>%tf%
ECHO:n5N2041LlBt3Bf0ma0X6ixXpW4ufiw9606I9s6vw001wW6f1[0X6yxhDO9>>%tf%
ECHO:j5f0Xpv4hDC91puxIs800esEyvRmA[0ml8f5Z\9Tj4v0hDC7F0M933pyW7>>%tf%
ECHO:ubiwu3hDW7tPFwkLlBtBHp3bpNxBi8f1f0XMG4g07D9TB200gLZfR62D09>>%tf%
ECHO:2GQn2lqyjX\n2Y]D36r6W900]Bq\N30101S000bD0[bD00070000000000>>%tf%
ECHO:0000000000000000000000000000000000000000000000000000000000>>%tf%
ECHO:0000000000000000000000000000000000000000000000000000000000>>%tf%
ECHO:00000000000000000000000000009\Tl9iS08j}>>%tf%
:: BASM source...
:: 'typical usage: type file | _replace "abc" "def" > newfile
:: 'replace all occurences of string "abc" with string "def"
:: 'read from standard input, write to standard output
:: $com
:: $string 512 'max line len
:: chr10$=chr$(10)
:: chr13$=chr$(13)
:: quote$=chr$(34)
:: 'parse command line...
:: c$=command$
:: c$=ltrim$(c$)      'get rid of surrounding spaces
:: c$=rtrim$(c$)
:: d$=left$(c$,1)
:: if d$<>quote$ then goto clerror
:: clen=len(c$)
:: clen=clen-1
:: c$=right$(c$,clen) 'remove 1st quote
:: qpos=instr(c$,quote$)  'get position of 2nd quote
:: if qpos<2 goto clerror 'must be at least 1 char
:: qpos=qpos-1
:: str1$=left$(c$,qpos) 'slice off match string
:: qpos=qpos+2
:: clen=len(c$)
:: rlen=clen-qpos
:: str2$=right$(c$,rlen) 'raw second half
:: str2$=ltrim$(str2$)  'no extra spaces
:: d$=left$(str2$,1)      'check for quotes
:: if d$<>quote$ then goto clerror
:: d$=right$(str2$,1)
:: if d$<>quote$ then goto clerror
:: clen=len(str2$)      'make sure valid string
:: if clen<2 then goto clerror 'too short
:: if clen>2 then            'at least 1 char
::  clen=clen-1
::  str2$=right$(str2$,clen)  'remove quotes
::  clen=clen-1
::  str2$=left$(str2$,clen)
:: else
::  str2$=""          'otherwise empty replace
:: end if
:: oneline$=""  'initialise main processing loop
:: linelen=0    'count chars to avoid overrun
:: mainloop:          'loop until no more...
:: a$=stdin$                   'get one character
:: if a$="" then goto nomore   'done with input
:: if a$=chr13$ then goto mainloop 'skip cr
:: if a$=chr10$ then           'if lf process line
::  gosub process               'replace and output
::  oneline$=""                 'reset string
::  linelen=0
::  goto mainloop               'and loop for more
:: end if                  'if not lf
:: if linelen<512 then      'if not overflow
::  oneline$=oneline$+a$     'add to line
::  linelen=linelen+1        'bump length count
:: end if
:: goto mainloop
:: nomore:
:: if linelen>0 then       'if extra chars w/ no crlf
::  gosub process           'process as one line
:: endif
:: end               'exit to dos
:: clerror:              'command line error
:: print "error"
:: end
:: process:                     'subroutine...
:: replace str1$ with str2$ in oneline$  'nice
:: output oneline$              'write to stdout+crlf
:: return
::-------------------------------
:: decode replace helper...
%dec% < %tf% > %replace%
if errorlevel 1 goto binerror
:: everything is in place to convert com into batch code...
::  %dec% - the decoder program
::  %enc% - encodes binary to text, stdin to stdout
::  %file2bat% infile outfile tmpfile - turns into echo code
::  %cmntsrc% file - outputs stdout with commented file
::  %replace% "search" "replace" - stdin to stdout
::  %compname% = the compiler name
::  %madewith% = utilities used to compile
::  %usetempdir% = yes if tempdir to be used
::  %decname% = decoder filename to use
::  %tempname% = temp filename to use
::  %fbase%.%outputext% = output filename
:: determine temp names...
set t=
if .%usetempdir%==.yes set t=%%temp%%.\
:: create output file...
set outfile=%fbase%.%outputext%
echo @echo off>%outfile%
echo>>%outfile% ::---- Generated by CONV2BAT ----
:: attach decoder...
echo>>%outfile% :: CM3-encoded DecBin decoder...
%file2bat% %dec% %tf1% %t%%decname%
type>>%outfile% %tf1%
:: attach encoded com file...
echo>>%outfile% ::---- EncBin-encoded binary ----
echo>>%outfile% :: %binfile% made with %madewith%
%enc% < %binfile% > %tf%
%file2bat% %tf% %tf1% %t%%tempname%
type>>%outfile% %tf1%
:: attach source code...
if not .%compname%==. echo>>%outfile% :: %compname% source...
if not .%compname%==. %cmntsrc% %fbase%.%fext% >>%outfile%
echo>>%outfile% ::-------------------------------
:: attach decode/run/delete lines...
echo>>%outfile% :: decode/run/delete, modify as needed...
echo>%tf1% %t%%decname% {{.lt{{ %t%%tempname% }}.gt}} %t%%binfile%
%replace% "{{.lt{{" "<" < %tf1% > %tf2%
%replace% "}}.gt}}" ">" < %tf2% >>%outfile%
if not .%compname%==. echo>>%outfile% %t%%binfile% %%1 %%2 %%3
if not .%compname%==. echo>>%outfile% del %t%%binfile%
if .%compname%==. echo>>%outfile% :: use %t%%binfile% as needed
echo>>%outfile% del %t%%tempname%
echo>>%outfile% del %t%%decname%
echo.
echo  ===========================================================
echo    Done! %binfile% is the raw binary
if exist %fbase%.asm echo    intermediate assembly is in %fbase%.asm
echo    %outfile% batch code recreates %binfile% when run
echo  ===========================================================
echo.
goto cleanup
:binerror
echo  Error in encoded binary
:cleanup
if exist %tf% del %tf%
if exist %tf1% del %tf1%
if exist %tf2% del %tf2%
if exist %enc% del %enc%
if exist %dec% del %dec%
if exist %replace% del %replace%
if exist %sepname% del %sepname%
if exist %cmntsrc% del %cmntsrc%
if exist %file2bat% del %file2bat%
:endCOPY
Tasm assembly source for the DecBin decoder... (before CM3 encoding)
;decbin.asm
;original code by Tenie Remmel - zdecode.asm from ASnip
;modified by Terry Newton to use 12 bit/64 char encoding
;verifies length, if not correct outputs ret and sets el=1
Ideal
Model Tiny
P186
CodeSeg
Org 100h
Proc        Program
            mov ah,3Fh         ;Read file/device
            xor bx,bx          ;handle for STDIN
            mov dx,1024        ;Start at DS:1K
            mov cx,63488       ;62K bytes (max)
            int 21h            ;DOS services
            mov si,1024        ;SI, DI = 1K
            mov di,si
            mov ah,'A'         ;AH = 'A'
            call GetDigit      ;First digit
            shl al,4           ;Shift over
            mov ch,al          ;Put in CH
            call GetDigit      ;Second digit
            or ch,al           ;OR into CH
            call GetDigit      ;Third digit
            shl al,4           ;Shift over
            mov cl,al          ;Put in CL
            call GetDigit      ;Last digit
            or cl,al           ;OR into CL
            push cx            ;Save numbytes
InpLoop:    lodsb              ;Load byte
            cmp al,21h         ;< 21h?
            jb InpLoop         ;Get new byte
            cmp al,'}'         ;Check for right bracket
            je Done            ;It's a right bracket, done
            ja InpLoop         ;Get new byte
            dec si             ;Re-load that byte
            lodsw              ;Load word
                ;first char in al, 2nd in ah
            xor dh,dh          ;Clear DH
            cmp al,5Eh         ;restore skip ^_` (mod...)
            jl AL_ok0
            sub al,3
AL_ok0:     cmp ah,5Eh
            jl AH_ok0
            sub ah,3
AH_ok0:     cmp al,3Ah         ;restore skip :;<=>?@ (mod...)
            jl AL_ok
            sub al,7
AL_ok:      cmp ah,3Ah
            jl AH_ok
            sub ah,7
AH_ok:
            sub ax,3030h       ;Adjust to binary (mod)
            mov dl,ah          ;Save remainder
            mov ah,64          ;Multiply by 64 (mod)
            mul ah
            add ax,dx          ;Add in remainder
            call Out12         ;Output 12 bits (mod)
            jmp InpLoop
Done:
            pop cx             ;Number of bytes (moved)
;verify size... (mod)
            mov ax,di          ;get output pointer
            sub ax,1024        ;subtract starting offset
            cmp ax,cx          ;compare actual vs recorded bytes
            je VerOK           ;if equal then cool
            dec ax
            cmp ax,cx          ;if actual is 1 more then cool
            jne VerNotOK       ;otherwise verify fails
            xor ax,ax          ;zero ax
            push ax            ;save for return value
VerOK: ;(stock minus pop plus label)
            mov ah,40h         ;Write file/device
            mov bx,1           ;handle for STDOUT
            mov dx,1024        ;Start at DS:1K
            int 21h            ;DOS services
       ;return errorlevel 0 or 1 depending on verify status
            pop ax             ;get saved errorlevel
            mov ah, 4Ch        ;exit function
            int 21h            ;do it
VerNotOK: ;here if size doesn't match (mod)
            mov cx,1           ;just one byte
            mov [byte ds:1024],0C3h ;make it a return
            push cx            ;save for return value
            jmp VerOK          ;write it
EndP        Program
Proc        GetDigit
DLoop:      lodsb
            cmp al,'A'
            jb DLoop
            cmp al,'P'
            ja DLoop
            sub al,'A'
            ret
EndP        GetDigit
;my code follows...
Split**    db 0     ;if not 0 then split byte
SplitByt    db 0     ;buffer
Proc        Out12    ;output 12 bits (to out buffer)
;on calling al/ah=Byte1/Byte2low, Byte3/Byte2high, Byte4/Byte5low
;                 Byte6/Byte5high, Byte7/Byte8low, etc (starting at 1)
            push bx cx
            mov bl,[Split**]  ;get even/split flag
            cmp bl,0
            je OutEven         ;if 0 then goto OutEven
            mov bl,[SplitByt]  ;get last split byte
            and bl,0Fh         ;low nibble
            shl ah,4           ;ah=high nibble
            or ah,bl           ;ah=reconstructed byte
            xchg ah,al         ;swap bytes
            stosb              ;store split byte
            mov al,ah          ;put split byte in al
            stosb              ;followed by whole byte
            mov [Split**],0   ;clear flag
            jmp Out12x         ;exit
OutEven:    mov [SplitByt],ah  ;save split byte low nibble
            stosb              ;store even byte
            mov [Split**],1   ;set split flag
Out12x:     pop cx bx
            ret
EndP        Out12
End ProgramCOPY
Tasm source for the EncBin encoder...
;encbin.asm
;original code by Tenie Remmel - zencode.asm from ASnip
;modified by Terry Newton for 12 bits per character pair
;batch-compatible encoding (64 possible values)
Ideal
Model Tiny
P186
CodeSeg
Org 100h
Proc        Program
            mov ah,3Fh         ;Read file/device
            xor bx,bx          ;handle for STDIN
            mov dx,24064       ;Start at DS:23.5K (mod)
            mov cx,40960       ;40K bytes (max) (mod)
            int 21h            ;DOS services
            mov cx,ax          ;Number of bytes in CX
            mov si,24064       ;SI = 23.5K (mod)
            mov di,1024        ;DI = 1K
            mov bx,2           ;BX = 2 (words)
            mov ah,'A'         ;AH = 'A'
            mov al,ch          ;First digit
            shr al,4           ;Shift over
            add al,ah          ;Adjust to text
            stosb              ;Store byte
            mov al,ch          ;Second digit
            and al,0Fh         ;AND mask
            add al,ah          ;Adjust to text
            stosb              ;Store byte
            mov al,cl          ;Third digit
            shr al,4           ;Shift over
            add al,ah          ;Adjust to text
            stosb              ;Store byte
            mov al,cl          ;Last digit
            and al,0Fh         ;AND mask
            add al,ah          ;Adjust to text
            stosb              ;Store byte
            add cx,si          ;CX = limit for SI
InpLoop:    call In12          ;Input 12 bits     (mod)
            mov dl,64          ;Divide AX by 64   (mod)
            div dl             ;now AL, AH <= 63
            add ax,3030h       ;Adjust to text 1st char="0" (mod)
            cmp al,3Ah         ;skip :;<=>?@ (mod...)
            jl AL_ok
            add al,7
AL_ok:      cmp ah,3Ah
            jl AH_ok
            add ah,7
AH_ok:      cmp al,5Eh         ;skip ^_` (mod...)
            jl AL_ok0
            add al,3
AL_ok0:     cmp ah,5Eh
            jl AH_ok0
            add ah,3
AH_ok0:
            stosw              ;Store word
            inc bx             ;Inc line counter
            cmp bx,29          ;58 chars on this line? (mod)
            jl Next            ;Jump if not
            xor bx,bx          ;Clear line counter
            mov ax,0A0Dh       ;Put a CRLF in AX
            stosw              ;Store it
Next:       cmp si,cx          ;SI > CX?
            jbe InpLoop        ;Jump if not
            mov al,'}'         ;Store bracket (ending char)
            stosb
            mov ax,0A0Dh       ;Put a CRLF in AX (added)
            stosw              ;Store it (added)
            mov ah,40h         ;Write file/device
            mov bx,1           ;handle for STDOUT
            mov cx,di          ;Number of bytes
            mov dx,1024        ;Start at DS:1K
            sub cx,dx          ;Adjust CX
            int 21h            ;DOS services
            ret                ;Exit
EndP        Program
;the following is my code...
SplitByt    db 0               ;buffer byte
Split**    db 0               ;even/split flag
Proc        In12
   ;return next 12 bits in ax, al=whole ah=fractions
   ;al/ah.. Byte1/Byte2low, Byte3/Byte2high, Byte4/Byte5low etc
            push bx cx        ;save regs
            mov cl,[Split**] ;get flag
            cmp cl,0
            je get2           ;if 0 then goto get2
            lodsb             ;get one more byte in al
            mov ah,[SplitByt] ;ah=left over bits from 2nd byte
            shr ah,4          ;top nibble
            mov [Split**],0  ;clear even/split flag
            jmp exin12        ;exit
get2:       lodsb             ;load byte into al
            push ax           ;save it
            lodsb             ;get next byte
            mov [SplitByt],al ;into buffer
            mov bl,al         ;save it
            pop ax            ;al=1st byte
            mov ah,bl         ;ah=2nd byte
            and ah,0Fh        ;ah=bottom nibble of 2nd byte
            mov [Split**],8  ;anything but 0
exin12:     pop cx bx         ;restore regs
            ret               ;back to caller
EndP        In12
End ProgramCOPY
Using Conv2Bat and Reusing Binary Batch Code

Download and install the compilers you wish to use, copy binaries that don't access libraries (such as basm, asm and the linkers) to a path directory, create linking batch files in a path directory for the larger compilers (asicc, mrc, tbc). For Windows, make shortcuts to the doc files of the compilers you're using or make printed copies, you'll need to refer to them often as you write code. If you want to be able to right-click and select "Convert to Batch" (or however named) use Windows' View|Options File Types dialog and add entries for asi, bas, moo and tok files as needed. You can also drag and drop the source file on top of the Conv2Bat.bat file or a shortcut to it. Conv2Bat should work fine in Dos 6, it contains no Windows-specific code but does need the Dos 6 or later FIND command to properly document whether or not PkLite was used. Under NT the comments in the output batch will likely be incorrect but the code output should be the same (if there are no other incompatibilities, have only tested with Win95Cmd).

Conv2Bat outputs batch code that writes the decoder to "_d.com", the temp file to "_t.tmp" and the actual decoded program to its original filename. Edit the output code as needed for your requirements. I often change the file targets to variables (like >>%tf%) to allow writing to the temp directory without requiring a long filename on each line. Once useful utilities have been created you can copy/paste them as needed into your batch files.

I just installed a new compact html browser called "Off By One" and wanted to be able to drag an html file onto the icon to load, but the browser wants to see a file:///c:/whatever type url for local files. Basically I needed a batch that converts a quoted long filename into a url that the browser can load. First I need to convert the long name into a short name (really to get rid of the quotes but doesn't hurt to be short so a simple for loop will do), prepend "file:///" to the quoteless name, and change "\" to "/". Here's what I come up in very little time using code copied from Conv2Bat...
:: OffByOne doesn't understand disk filenames like "c:\web\file.htm"
:: Convert parm to "file:///" + name without quotes and change \ to /
@echo off
set url=
if .%1==. goto noparm
if not exist %1 goto noparm
set dec=%temp%.\_dec.com
set tf=%temp%.\_tmp.tmp
set replace=%temp%.\_rep.com
::-----------------------
:: CM3-encoded DecBin decoder...
ECHO:`h}aXP5y`P]4nP_XW(F4(F6(F=(FF)FH(FL(Fe(FR0FTs*}`A?+,>%dec%
ECHO:fkOU):G*@Crv,*t$HU[rlf~#IubfRfXf(V#fj}fX4{PY$@fPfZsZ$:NvN$>>%dec%
ECHO:9AyroNB-)dOKwK0rRkfTbi)ws_~[[q9wE'sqlu1sY*Bsfe=@ziNS1a)88e>>%dec%
ECHO:f9RTL)9Z{3INBD?o6@MDLO{Zz4Q23E-'09NX9@Vz(42A7c8zMS:u$w6k5Q>>%dec%
ECHO:N,h:le)~gF?tutTyxoe5UiIdtn';0rJ1q:{7;lAl']y:yTjZBbOo?QRIdN>>%dec%
ECHO:$Bp@P/nAp_r0*4f'XcF4q3o?$_t5lx$Q-OxSfUNQ__Gd~$Q-Oxgkx=LGHU>>%dec%
ECHO:S)$C6P8#>>%dec%
::---- EncBin-encoded binary ----
:: replace.com made with BASM ASM FREELINK
ECHO:AGINr64U2y00tD61O0AAj7CDXn28Q587D7JeRkl5S]00xG47uvfav7f][7>%tf%
ECHO:gGC0v]U[2uMDA13301EBu1Je13dnJDrX5OYZ47dZ47Fbv2ibO5pyW9dr00>>%tf%
ECHO:M90maRXTW1s3v3hDWJs[W5sIv5hDW9fD[0W5fmp95T3bCd2yMD7bLB3bKs>>%tf%
ECHO:2y]D2r0Y29C5FRp9K17b43pyWNBbC53b85Qx87pyWPNbj2Jb45pxWPabK4>>%tf%
ECHO:Fbv2pyWPJb45Bb05pxWPZb447br2pyWPBb053bv45d1b]D7bI93bBD2yhD>>%tf%
ECHO:7bJh2xhD6yUD7bB81of3r4]Gr7C2F0tZ47pxWPabS2O30UC7cqv7vETq3b>>%tf%
ECHO:Io3ySpS7obWPJbO43b[2pyWP7bf40mlZSU2y]D6xUD7bC]03r647]ZS7t3>>%tf%
ECHO:Ds871vf3r1xGvETs3bHv3y[pS7obWPFb44VbK2pyWTZbS4Q31s870mF0bU>>%tf%
ECHO:r7hDWPrFC206SU2ZTq0mF006Tq0e[6S7hZS7BbG4RyDuW7QDWPukW3rTv2>>%tf%
ECHO:hDWVrxW4rfr4hDWVskW3rBv2hDWVrfW4rQb4O1obWVFbf3Vbv1pyWRZb44>>%tf%
ECHO:pxWRpyWNBbv1Do3e04ac4k3bFo1dW1QDWVt]W3uIv1hDWRumr3hDvRhDWN>>%tf%
ECHO:uDK1S3Je2Gmc010mlZSU2xxD7b5x03r647UZS7t3Dq871vf3r4]GugC0Wx>>%tf%
ECHO:Tq02Dy3e0raySES7Fbb3RyDqW7QDWVsIW3sxv1hDWVtVv3vETq3bE93ySp>>%tf%
ECHO:S7obWV3b83JbO1pyWVNbW3qe2G3bS3pxS7pyWVNb41JbO3xxS7pyWXab01>>%tf%
ECHO:R7210700BbK3ubS3JbC1pyWZNbK3pxWZEyW7yb81Dn3e04ae1S]xEDAyMD>>%tf%
ECHO:7b4U1nf3r3hGuGpxWZpyWJub01Dn3e0Oab1V3bCH2xU52y6DBb2p3746W7>>%tf%
ECHO:003e6eWxU100j2S3ee6GBbv2pxWXJbv2pxWZubr2pyWXybr2Ry21f7t5t3>>%tf%
ECHO:E1071yf3r4YGrO00f0lnJDrXh7W7tHW1sQW0rc02f0lnJDrXhDvThDWBsQ>>%tf%
ECHO:r0hDvVhDWDsHr0hDvXhDWFs8W0tPr0hDv7hDWXrvW0QDWXtUW2OFW7tOC2>>%tf%
ECHO:ln9CF07DAn83Fy3D4me0Z23xlZS62Au6y0YZ07i3WMS63x7Ab8b7Zjuxln>>%tf%
ECHO:n2jGm3xfdd30coy3PHLNtBvla0iymyylUhyHg9Z1sVLP73LNPMLNXUuXiy>>%tf%
ECHO:ZOXUuRiyZ8s1LVf3yvRmA[DPlx]D2yUD3byRy3TGLMmvdhHo0AN0VrwULO>>%tf%
ECHO:N3MBFfZfv6hDOHj5v0hDO7j5r0hDWFtSayX6uxhDWBtJayX6FvF0Q9JtRy>>%tf%
ECHO:JtQBJtOuJxXyMxxD2y]D03cpwEtBJvFvv]E[F0M82x]D2y6D7bwQxx6D6y>>%tf%
ECHO:hD3bxLworLhDvDhDW7s[iyX67v16ytwEitrPtGhDvFhDC91putIs013vRm>>%tf%
ECHO:A[0ml8W5sSiytTMBsTN3NbvWxBROMBZqrOiyZGgUZhkBwNMBxfdBmlMhSS>>%tf%
ECHO:6BpBFBx]gn03isBuCuoqiarAhGBuUBkRCekTF3F0oRN3FbuxgGZ8]3v0gx>>%tf%
ECHO:EBbU07YX07tBC6r746w8I33y1yC2Fy2tK0Bqr37rqa2r2j2ElnnFjGSv1n>>%tf%
ECHO:W5f0trZ0Jvb]p857ZYv7WVK1O607y3hDWBtCuxhDvBhDW9t3uxhDW9t5yx>>%tf%
ECHO:hDf9Z8W3xA0TZuvWSB0ml8[5HF]3v0swu3pyWBqbNxpxWB[ml00v9oO8H1>>%tf%
ECHO:]1v0K2Vm2s02pyW9Fvv]E[m7O607013yW607t3C8b75ov4vES82tSC2nn9>>%tf%
ECHO:jXtB46b7ZJexlBWU07EAyxFEFRAn3DCGkLlBtBHp2y]D2BPE3vRmA[0ml8>>%tf%
ECHO:n5N2041LlBt3Bf0ma0X6ixXpW4ufiw9606I9s6vw001wW6f1[0X6yxhDO9>>%tf%
ECHO:j5f0Xpv4hDC91puxIs800esEyvRmA[0ml8f5Z\9Tj4v0hDC7F0M933pyW7>>%tf%
ECHO:ubiwu3hDW7tPFwkLlBtBHp3bpNxBi8f1f0XMG4g07D9TB200gLZfR62D09>>%tf%
ECHO:2GQn2lqyjX\n2Y]D36r6W900]Bq\N30101S000bD0[bD00070000000000>>%tf%
ECHO:0000000000000000000000000000000000000000000000000000000000>>%tf%
ECHO:0000000000000000000000000000000000000000000000000000000000>>%tf%
ECHO:00000000000000000000000000009\Tl9iS08j}>>%tf%
:: BASM source...
:: 'typical usage: type file | _replace "abc" "def" > newfile
:: 'replace all occurences of string "abc" with string "def"
:: 'read from standard input, write to standard output
:: $com
:: $string 512 'max line len
:: chr10$=chr$(10)
:: chr13$=chr$(13)
:: quote$=chr$(34)
:: 'parse command line...
:: c$=command$
:: c$=ltrim$(c$)      'get rid of surrounding spaces
:: c$=rtrim$(c$)
:: d$=left$(c$,1)
:: if d$<>quote$ then goto clerror
:: clen=len(c$)
:: clen=clen-1
:: c$=right$(c$,clen) 'remove 1st quote
:: qpos=instr(c$,quote$)  'get position of 2nd quote
:: if qpos<2 goto clerror 'must be at least 1 char
:: qpos=qpos-1
:: str1$=left$(c$,qpos) 'slice off match string
:: qpos=qpos+2
:: clen=len(c$)
:: rlen=clen-qpos
:: str2$=right$(c$,rlen) 'raw second half
:: str2$=ltrim$(str2$)  'no extra spaces
:: d$=left$(str2$,1)      'check for quotes
:: if d$<>quote$ then goto clerror
:: d$=right$(str2$,1)
:: if d$<>quote$ then goto clerror
:: clen=len(str2$)      'make sure valid string
:: if clen<2 then goto clerror 'too short
:: if clen>2 then            'at least 1 char
::  clen=clen-1
::  str2$=right$(str2$,clen)  'remove quotes
::  clen=clen-1
::  str2$=left$(str2$,clen)
:: else
::  str2$=""          'otherwise empty replace
:: end if
:: oneline$=""  'initialise main processing loop
:: linelen=0    'count chars to avoid overrun
:: mainloop:          'loop until no more...
:: a$=stdin$                   'get one character
:: if a$="" then goto nomore   'done with input
:: if a$=chr13$ then goto mainloop 'skip cr
:: if a$=chr10$ then           'if lf process line
::  gosub process               'replace and output
::  oneline$=""                 'reset string
::  linelen=0
::  goto mainloop               'and loop for more
:: end if                  'if not lf
:: if linelen<512 then      'if not overflow
::  oneline$=oneline$+a$     'add to line
::  linelen=linelen+1        'bump length count
:: end if
:: goto mainloop
:: nomore:
:: if linelen>0 then       'if extra chars w/ no crlf
::  gosub process           'process as one line
:: endif
:: end               'exit to dos
:: clerror:              'command line error
:: print "error"
:: end
:: process:                     'subroutine...
:: replace str1$ with str2$ in oneline$  'nice
:: output oneline$              'write to stdout+crlf
:: return
::-------------------------------
:: decode replace helper...
%dec% < %tf% > %replace%
del %dec%
del %tf%
:: convert parameter into url...
:: first get rid of quotes...
for %%a in (%1) do set file=%%a
:: create set for new url...
echo set url=file:///%file% > %temp%.\tf1.tmp
:: use helper utility to change \ to /
%replace% "\" "/" < %temp%.\tf1.tmp > %temp%.\tf2.bat
:: run results to set url var...
call %temp%.\tf2.bat
:: clean up...
del %temp%.\tf2.bat
del %temp%.\tf1.tmp
del %replace%
:: run browser...
:noparm
"c:\Program Files\hpsw\OffByOne\ob1.exe" %url%COPY
Batch file size is increased, perhaps too much for some tastes, but I don't think that's a huge disadvantage. It does require about 3 seconds to launch rather than 1 second just running the program but a single batch line starting the browser takes almost as long (bin-batch adds only a fraction of a second) and it doesn't matter anyway considering 3 seconds is about 4 times faster than opening Netscape or IE. It doesn't bother me that two com files are created and deleted in my temp directory, it looks scary and takes more bytes, I'm happy I can drag a file to OffByOne and it only took a few minutes to accomplish using a search and replace helper ripped as-is from another bin-batch. I could make it smaller by writing custom code that directly changes "\" to "/" but that would have take longer.. it's faster to copy/paste existing code than write new code if the existing code does the job, the number of lines doesn't figure unless so large it impedes things in other ways.. like when notepad will no longer load the batch. In today's world of multi-megabyte programs a bloated batch is insignificant. I could save space and make the replace utility a persistent file and not encode at all, but then I'd have another utility on my path to keep up with, not worth saving a few kilobytes. Echoed QBasic scripts can do just about anything bin-batch can do, but there's a screen flash, QBasic.exe must be available, and not being able to use "<" or ">" in the code complicates comparisons. Whatever works.

Links to binary batch code and compiler resources

Herbert Kleebauer's Convert.bat (Google)
UBE.zip contains Convert.bat, source and other "ascii assembler" routines
Ass486.zip contains Herbert Kleebauer's 68K-like assember
Laura Fairhead's CM3 utility · alternate page
Disassembly of CM3 by Herbert Kleebauer (Google)
Disassembly of CM3's decoder by Laura Fairhead (Google)
The Moonrock Compiler Page


--------------------------------------------------------------------------------


(C) Copyright 2003 by Terry Newton
http://www.infionline.net/~wtnewton
1

评分人数

    • CrLf: 好资料!技术 + 1
天的白色影子

TOP

@echo off
if exist %0.bat %0.bat
echo Bj@jzh`0X-`/PPPPPPa(DE(DM(DO(Dh(Ls(Lu(LX(LeZRR]EEEUYRX2Dx=>h2b.com
echo 0DxFP,0Xx.t0P,=XtGsB4o@$?PIyU WwX0GwUY Wv;ovBX2Gv0ExGIuht6>>h2b.com
echo ?@}I{uNWEF~NFAa_Lj@KLtH]~CEvEFIKbAa_wN@SuNS`{ECCttasae~BHM>>h2b.com
echo AcjFnvnHAwrvx[}gIKDw??Frt\gqj~{?s?csIsqo{O_KtBve{Sx{nB{Eu@>>h2b.com
echo fq`tkfk?e@oKCA_?_E@?WxAs?agBwRjnLK?s@w`G`LKLAcyA?@xAsZpk`L>>h2b.com
echo ~KxlqLct@vAc_A_yBJ@xAGZp?o?sBXq`LR@xUrFQt=A_E?B?~rB?~r0>>h2b.com

h2b "::f1" <%0 >bild1.gif
h2b "::f2" <%0 >bild2.gif
h2b "::f3" <%0 >demo.com
del h2b.com

:: hex dump of bild1.gif
::f1 4749463839614b001100a20000140b00fffbf7ff6600fffcfa0000000000
::f1 000000000000002c000000004b0011000003a228badcfe30ca0901bd386b
::f1 66b7ff5f078e64242a419aa2eabaa84cebb2731d2cc39357f1cd0ab306ec
::f1 e503fa5cc8e26cc06c30778d53f0e758d988c6c715f7643ca10ae9902abc
::f1 6db35372faebed86cb4399d23c6f917b32079bdb7c576169687354816702
::f1 7b0a887e5a747f79593f8583897d7c0f6258695b9b479d58893a26704976
::f1 909041a493a61e2725ae25adafb2acb3b52100b8b9babbbcbdbebfc0c1bf
::f1 09003b

:: hex dump of bild2.gif
::f2 47494638396121001000b30000fffdfbff6702ffc39aff9e5effdfcaffef
::f2 e5fff8f4ffffffc0c0c00000000000000000000000000000000000000000
::f2 0021f90401000008002c0000000021001000000463f0c849abbd385f3384
::f2 fe9911041e2811432a1499300e00388c743010d83ce26deddf16110d78d1
::f2 f96a1dd6c485e4518ed0a1406044962451a80aa5751eaadd0a73a8a48c8f
::f2 83f2a480548bd1ee892e0d2a4c05841886793581847d7e1f007882862611
::f2 003b

:: hex dump of an executable
::f3 fcbe3301bf4301b95000b020f3aa89fab91000f3a4bbffffb93c00b409cd
::f3 21b40bcd2108c0750801dae2f0f7dbebe9b44ccd21707265737320616e79
::f3 206b65790d0a24

;我想知道SERCH.GIF的二进制码,人类是如何凭空想出来,写出来的,bird.gif又是如何来的,唱歌说,用HEX工具编辑GIF文件复制出来,那是没有任何意义的,那样使用这种BAT纯纯的自我欺骗

TOP

回复 11# bluenightsky


    h2b 这个名字已经说明了一切,真就是 Bin To Hex 再 Hex To Bin 的把戏

TOP

@echo off
chcp 437 >nul
echo Bj@jzh`0X-`/PPPPPPa(DE(DM(DO(Dh(Ls(Lu(LX(LeZRR]EEEUYRX2Dx=>echoo.com
echo 0DxFP,0Xx.t0P,=XtGsB4o@$?PIyU!WvX0GwUY Wv;ovBX2Gv0ExGIuht6>>echoo.com
echo ?@xAyJHmH@=a?}VjuN?_LEkS?`w`s_{OCIvJDGEHtc{OCIKGMgELCI?GGg>>echoo.com
echo EL?s?WL`LRBcx=k_K?AxVD?fCo?Cd?BLDs0>>echoo.com
echoo $31$30$30$25$20$b4$bf$cf$e3$d3$cd$0d$0a>~tmp.txt
chcp 936 >nul
type ~tmp.txt
pauseCOPY

TOP

返回列表