CAPIx 2.0 帮助
141 |Table of Contents
143 |-
145 |
- 1. 简介 146 |
- 2. 标识符 147 |
- 3. 基本命令
148 |
-
149 |
- 3.1. Mem
150 |
-
151 |
- 3.1.1. Alloc 152 |
- 3.1.2. Free 153 |
- 3.1.3. Put 154 |
- 3.1.4. Print 155 |
- 3.1.5. Copy 156 |
- 3.1.6. 用途 157 |
159 | - 3.2. API
160 |
-
161 |
- 3.2.1. Call 162 |
- 3.2.2. Exec 163 |
- 3.2.3. 注 164 |
166 | - 3.3. CAPIDll 167 |
- 3.4. Var
168 |
-
169 |
- 3.4.1. SetCall 170 |
- 3.4.2. GetCall 171 |
173 |
175 | - 3.1. Mem
150 |
- 4. 实例
176 |
-
177 |
- 4.1. Mem Alloc Free 178 |
- 4.2. Mem Put 179 |
- 4.3. Mem Copy 180 |
- 4.4. Mem Print 181 |
- 4.5. API Call 182 |
- 4.6. API Exec 183 |
- 4.7. GetCall 184 |
186 | - 5. CAPx相对CAPI有哪些改进 187 |
- 6. 等待加入的功能 188 |
1 简介
194 |196 | 致敬D大和他的CAPI(注入版) 197 |
198 | 199 |200 | 简介: 201 |
202 | 203 |204 | CAPI是bathome的defanvie开发的一款第三方,堪称批处理第三方的登峰造极之作 205 |
206 | 207 |208 | CAPI提供的最大功能就是一个:调用系统API 除此之外,CAPI并没有任何功能 209 |
210 | 211 |212 | 而且其注入式的特点,一方面使得其调用速度得到了飞一般的提升,另一方面也使得其能够保存进程数据 213 |
214 | 215 |216 | 这两个功能,赋予了CAPI无穷的力量 217 |
218 | 219 |220 | 何为系统API?简而言之,是MS为了便利开发者,而封装在dll中的一系列函数 221 |
222 | 223 |224 | 通过这些函数,开发者可以不需要理解系统的内部原理就方便地开发出产品 225 |
226 | 227 |228 | 比如著名的image(第一代),就是调用了gdi32中的API从而实现了绘图功能 229 |
230 | 231 |232 | 而利用CAPI,我们可以轻松地实现这个功能,而且由于CAPI是注入式的,我们可以甚至可以实现双缓冲 233 |
234 | 235 |236 | 即先把图片画到内存中的画布上,等待所有的图片都绘制完成,再将整块画布复制到CMD中 237 |
238 | 239 |240 | 这样做的最大好处就是可以避免闪烁,实现流畅地绘制 241 |
242 | 243 | 244 |245 | 然而CAPI有几个问题,导致了它虽然强大,但却很少被使用 246 |
247 | 248 |249 | 1.采取远程线程注入的方法将dll注入到cmd中,这是病毒的常用伎俩,因此误杀率极高 250 |
251 | 252 |253 | 2.开发者defanvie已经很久没有现身,而且CAPI没有开源.已经无法在最新的系统上运行了 254 |
255 | 256 | 257 |258 | CAPIx就是为了解决这两个问题而开发的 259 |
260 | 261 |262 | 首先CAPIx摒弃了远程线程注入的方式,而是使用一个修改过的提取自win 2003的cmd 263 |
264 | 265 |266 | 这个cmd在启动时会自动加载CAPIx.dll,免去了注入的危险 267 |
268 | 269 |270 | 其次CAPIx的开发者是可以联系到的,而且CAPIx完全开源,这为修复bug和增加功能提供了方便 271 |
272 | 273 |274 | 并且CAPIx在API调用的功能上做出了进一步的加强 275 |
276 | 277 |278 | 在API Call之外又提供了一个新命令API Exec,用来调用遵循__cdecl约定的函数 279 |
280 | 281 |282 | 简而言之,可以调用其他dll中的函数,比如msvcrt中的大部分函数,像printf, scanf之类的 283 |
284 | 285 |286 | 又比如调用regex2.dll实现正则匹配,还可以自己写dll供Exec调用,比如写一个浮点运算的dll代替set/a之类的 287 |
288 | 289 |290 | CAPIx潜力无限! 291 |
292 | 293 |294 | 下载地址: https://github.com/YinTianliang/CAPIx/tree/master/bin 295 |
296 | 297 |298 | 请务必下载CAPIx.dll和cmd.exe, CAPIx_Help.html为详细帮助,建议下载 299 |
300 | 301 |302 | 使用CAPIx进行的程序只能在上面这个cmd.exe中正常运行 303 |
304 | 305 |306 | 所以建议使用以下JS启动游戏(该cmd.exe需要与js, capix.dll放在同一目录下) 307 |
308 | 309 |1: new ActiveXObject('WScript.Shell').Run('"' + WScript.ScriptFullName.replace(/[^\\]*$/,'') + 'cmd.exe" /c 游戏主程序.bat') 312 |313 |
316 | 或者在批处理开头加上这两行 317 |
318 | 319 |1: %1@start "" "%~dp0cmd.exe" "/c %~fs0 :" 322 | 2: %1@exit 323 |324 |
327 | 为了兼容以前的的CAPI作品, CAPIx的语法和CAPI是一样的, 只是在此基础之上做了加强, 使之更加人性化 328 |
329 | 330 |331 | 本文档中的大部分内容来自http://www.bathome.net/thread-19238-1-1.html 332 |
333 |2 标识符
338 |340 | 标识符用来添加在参数前面, 指定这个参数的类型 341 |
342 || 符号 | 355 |大小 | 356 |意义 | 357 |
|---|---|---|
| . | 362 |1B | 363 |字节 | 364 |
| : | 368 |2B | 369 |短整形 | 370 |
| ; | 374 |4B | 375 |长整形 | 376 |
| ~ | 380 |4B | 381 |浮点型 | 382 |
| ` | 386 |8B | 387 |双浮点型 | 388 |
| # | 392 |- | 393 |字符串(ANSI) | 394 |
| $ | 398 |- | 399 |字符串(Unicode) | 400 |
| * | 404 |4B | 405 |变量(的地址),相当于C语言中的&.可以后跟"; # $ "表示这个指针指向的变量的类型,默认为$ | 406 |
| @ | 410 |- | 411 |移动指针,后跟欲移动的距离,可以为负 | 412 |
3 基本命令
420 |3.1 Mem
423 |3.1.1 Alloc
426 |428 | Mem Alloc [size] 429 |
430 |-
431 |
- 用途:申请一块内存 432 | 433 |
- 参数:[size]为该内存块的大小 434 | 435 |
- 返回值:该内存块的地址 436 | 437 |
- 注意:内存不用时需要释放, 避免造成内存泄漏 438 | 439 |
3.1.2 Free
444 |446 | Mem Free [addr] 447 |
448 |-
449 |
- 用途:释放一块内存 450 | 451 |
- 参数:[addr]为欲释放的内存地址 452 | 453 |
3.1.3 Put
458 |460 | Mem Put [s][addr] [s][data] [s][data] … 461 |
462 |-
463 |
- 用途:将数据按格式写入内存地址中 464 | 465 |
- 参数:[s][addr]为欲写入的地址, [s]可选"; *". [s][data]为欲写入的数据, [s]可选". : ; ~ ` # $ * @" 466 | 467 |
- 注意:写入的数据量若超过该内存块的大小可能导致cmd崩溃 468 | 469 |
3.1.4 Print
474 |476 | Mem Print [s][addr] [s][var] [s][var] … 477 |
478 |-
479 |
- 用途:将指定地址处的内容输出到变量中 480 | 481 |
- 参数:[s][addr]为内存地址, [s]可选"; *". [s][var]为输出参数, [s]可选". : ; ~ ` # $ * @", [var]为变量名 482 | 483 |
3.1.5 Copy
488 |490 | Mem Copy [s][dst] [s][src] [sz] 491 |
492 |-
493 |
- 用途:将源地址的一段内存复制到目标地址 494 | 495 |
- 参数:[s]可选"; *" 496 | 497 |
3.1.6 用途
503 |505 | Mem系列的命令提供了对内存的操作,其最大的意义就在于实现结构体或数组 506 |
507 | 508 |509 | 使用时要注意结构体的对齐 510 |
511 |3.2 API
516 |3.2.1 Call
519 |521 | API Call [dll] [s][API] [s][data] [s][data] … 522 |
523 |-
524 |
- 用途:调用遵循__stdcall约定的函数(一般为WINAPI) 525 | 526 |
- 参数:[dll]为dll相对路径, [API]为API函数全名, [s]为返回值类型, 默认为";", 可选"~ `". [s][data]为参数, [s]可选"; ~ ` $ # *" 527 | 528 |
- 返回值:该API的返回值 529 | 530 |
3.2.2 Exec
535 |537 | API Exec [dll] [s][API] [s][data] [s][data] … 538 |
539 |-
540 |
- 用途:调用遵循__cdecl约定的函数(一般除WINAPI以外都是) 541 | 542 |
3.2.3 注
547 |549 | API是可以指定返回值类型的 550 |
551 | 552 |553 | 以上两个命令的[s][API]可以用该函数在内存中对应的地址来表示,此时[dll]应为"0" 554 |
555 | 556 |557 | 如set CAPI=API Exec 0 16777215 ;0 ;1 558 |
559 |3.3 CAPIDll
565 |-
567 |
- CAPIll /?
- 返回CAPIx的基本信息 568 | 569 |
- CAPIDll Ver
- 返回CAPIx的版本, 保存在变量CAPI_Ret中 570 | 571 |
3.4 Var
577 |3.4.1 SetCall
580 |-
582 |
- SetCall Enable
- 开启SetCall调用方式,即set CAPI=xxxx,返回值在变量CAPI_Re中t 583 | 584 |
- SetCall Disable
- 关闭SetCall调用方式(默认开启) 585 | 586 |
3.4.2 GetCall
591 |-
593 |
- GetCall Enable
- 开启GetCall调用方式,即echo %CAPI xxx%,返回值即%CAPI xxx%扩展的结果 594 | 595 |
- GetCall Disable
- 关闭GetCall调用方式 596 | 597 |
4 实例
605 |4.1 Mem Alloc Free
608 |1: @echo off 612 | 2: set "CAPI=Mem Alloc 4" 613 | 3: set "lpAddress=%CAPI_Ret%" 614 | 4: echo %lpAddress% 615 | 5: pause 616 | 6: set "CAPI=Mem Free %lpAddress%" 617 | 7: pause 618 |619 |
621 | 创建了一块大小为4的内存,内存地址保存在lpAddress里
622 | 在批处理第一次暂停时,使用工具查看cmd.exe内存,可以看到在输出的地址处为4个空白字节的内存,第二次pause时,可以看到内存已经被释放
623 |
4.2 Mem Put
628 |1: @echo off 632 | 2: set var=hello 633 | 3: set data=0123456789 634 | 4: set "CAPI=Mem Put *data .97 @1 :25105 #ab $ab *var" 635 | 5: echo %data% 636 | 6: pause 637 |638 |
640 | 执行前data变量的内存内容为30 00 31 00 32 00 33 00 34 00 35 00 36 00 37 00 38 00 39 00
641 | 执行写入命令时,此时指针指向第1个字节,.97将1个字节为97写入,于是变成了61 00 31 00 …,指针后移1位,指向第2个字节
642 | @1将指针后移1位,此时指针指向第3个字节
643 |
645 | :25105,此时指针指向第3个字节,将2个字节为25105写入,于是变成了61 00 62 11 32 00 …,指针后移2位
646 | #ab,此时指针指向第5位,将2个字节的ANSI字符串ab写入,于是变成了61 00 62 11 61 62 33 00 34 00 …,指针后移2位
647 | $ab,此时指针指向第7位,将4个字节的Unicode字符串ab写入,于是变成了61 00 62 11 61 62 61 00 62 00 …,指针后移4位
648 | /h*var,此时指针指向第11位,将var变量h的内容全部写入
649 |
4.3 Mem Copy
654 |1: @echo off 658 | 2: set var=hello 659 | 3: set data=0123456789 660 | 4: set "CAPI=Mem Copy *data *var 6" 661 | 5: echo %data% 662 | 6: pause 663 |664 |
666 | 执行时,将var变量的前4个字节复制到data变量中,即是“hel”
667 | 因此输出“hel3456789”
668 |
4.4 Mem Print
673 |1: @echo off 677 | 2: set var=0123456 678 | 3: set "CAPI=Mem Print *var .output_1 @2 :output_2 @1 #output_3 $output_4" 679 | 4: set output_ 680 | 5: pause 681 |682 |
684 | var变量的内容为30 00 31 00 32 00 33 00 34 00 35 00 36 00
685 | .output_1,此时指向第1个字节,将1字节的内容“31”放入output_1变量中,也就是48
686 | @2,此时指针指向第2个字节,将指针后移2位,此时指针指向第4个字节
687 | :output_2,此时指针指向第4个字节,将2字节的内容“00 32”放入output_2变量中,也就是12800
688 | @1,此时指针指向第6个字节,将指针后移1位,此时指针指向第7个字节
689 | #output_3,此时指针指向第7个字节,将接下来的内容作为ANSI字符串放入output_3变量中,也就是“33”,字符串3
690 | $output_4,此时指针指向第9个字节,将接下来的内容作为Unicode字符串放入output_4变量中,也就是“34 00 35 00 36 00”,字符串456
691 |
4.5 API Call
697 |1: @echo off 701 | 2: set "data=message" 702 | 3: set "CAPI=API Call user32 MessageBoxW ;0 *data $title ;1" 703 | 4: echo %CAPI_Ret% 704 | 5: pause 705 |706 |
708 | 调用API MessageBox,第一个参数为0,第二个参数为data变量的地址,第三个参数为Unicode字符串title,第四个参数为1
709 | 由于CMD内部将变量data储存为Unicode,因此应使用Unicode版本的API,也就是MessageBoxW
710 | (注:CAPIx的*标识符得到了增强,可以使用*#data来强制将data转换为ANSI字符串)
711 |
4.6 API Exec
717 |1: @echo off 721 | 2: set "data=123|456|789" 722 | 3: set CAPI=API Exec msvcrt sscanf *#data "#%d|%^d|%d" *;_1 *;_2 723 | 4: echo %_1% %_2% 724 | 5: pause 725 |726 |
728 | 调用C语言库函数sscanf,该函数遵循cdecl调用协定,因此只能使用Exec调用
729 | 第一个参数*#data表示取变量data的内容, 转换为ANSI字符串, 第二个参数为sscanf的Format, 第三个和第四个参数取了两个整形变量地址
730 |
1: @echo off 736 | 2: set "CAPI=API Exec msvcrt `sqrt `666" 737 | 3: echo %CAPI_Ret% 738 | 4: pause 739 |740 |
742 | 调用C语言库函数sqrt,且指定返回值类型为双浮点数 743 |
744 | 745 |1: @echo off 748 | 2: set "CAPI=API Exec msvcrt scanf "#%d %d" *;_1 *;_2" 749 | 3: echo %_1%, %_2% 750 | 4: pause 751 |752 |
754 | 调用C语言库函数scanf, *;_1 的意思是取环境变量_1的地址,将其当作整形变量传给scanf 755 |
756 |4.7 GetCall
761 |1: @echo offh 765 | 2: set CAPI=Var GetCall Enable 766 | 3: set lpAddress=%CAPI Mem Alloc 4% 767 | 4: echo 申请的内存地址为:%lpAddress% 768 | 5: set CAPI=Mem Free %lpAddress% 769 | 6: pause 770 |771 |
5 CAPIx相对CAPI有哪些改进
778 |-
780 |
- "@"可以接受负值 781 | 782 |
- 参数类型中增加了浮点数和双浮点数 783 | 784 |
- 为函数返回值提供了类型 785 | 786 |
- "*"可以通过后跟"; # $"来指定该变量类型 787 | 788 |
- "*"不只是取变量内容, 而是取变量地址.API对该地址的修改会同步到变量中 789 | 790 |
- "Exec"命令的加入 791 | 792 |
- 可以运行内存中的函数 793 | 794 |
6 等待加入的功能
799 |-
801 |
- COM调用 802 | 803 |