欢迎使用 WordPress。这是您的第一篇日志。您可以编辑它或是删除它,然后开始写您自己的博客。
-
最新日志
最新评论
- amnesiac 发表于《在脚本中使用Send发送中文》
- 中国博客网 发表于《Hello world!》
- 中博网友 发表于《Wireshark 简介 [原]》
- 中博网友 发表于《代码/DLL注入工具 [CodeInjector v1.1]》
- 海洋之星墙艺漆 发表于《搬家了》
存档页
分类
功能
搬家到cnblogs了,这里暂时不打算继续更新了(虽然本来就很久没更新的说,
)。
就这样。
新blog地址:http://www.cnblogs.com/yonken/
其实很久之前就看到有朋友说希望开源,可是因为很多原因,虽然想解释,但我这人很懒,也就没有回复。
不过刚刚下班回来,看到一个留言:
介于博主的不仗义,我这里贴出,od提供的源码。汇编和反汇编源码(GNU)。
下载地址: http://www.ollydbg.de/srcdescr.htm
如果没猜错的话,博主也是使用这个SDK了。
Bingo! 这位朋友猜的没错,正是用了OD的!
下面是自问自答时间:
Q:为什么不开源?
A:汗,因为代码写的很随便,有些恶心的BUG,代码简直不堪入目,所以为了避免恶心到别人。。。
第二个原因是正如前面这位朋友说的那样,并没有任何含金量,只不过是用了人家的SDK罢了,更加没有所谓开源的理由了。
Q:当初弄这个的目的?
A:当时对注入代码和DLL感兴趣,有想法,就写了,就这么简单。
Q:不是说要支持变量定义吗?
A:确实是有这个打算,刚开始是想改SDK的代码,后来因为工作原因没有动手,再后来在公司正好有在做相关工作(解释执行C++代码),就开始想是不是干脆也弄个解释执行的,把解释引擎和脚本同时注入到目标进程里面然后解释执行脚本。再再后来。。
发现其实这是重复开发,何不干脆用现成的,现在已有很多优秀的这类代码可以实现了,比如 TinyCC,所以现在也是打算直接用人家的包装一下就OK了!不过这也是要遇上好的时间和心情才行啊。
各位大哥,我不过是在自己的博客上胡言乱语罢了,可不是在给谁什么承诺哦,对吧?
最后,至于仗义不仗义,我不解释,博客就是给人满足自己的各种无聊的心理需求的平台罢了,没必要跟现实生活中那样维护自己甚至伪装自己(尽管依靠网络本身就是很好的伪装了)。
前阵子在公司写了个递归函数,在公司自己的语言环境下run了一下,慢的受不了,程序简直就是停止响应了,于是在VC下测试时间,发现居然是0
没办法,毕竟是解释执行的代码。
然后就想到好久没碰过的脚本,于是分别在AU3和AHK下写了个最简单的递归版fibonacci的脚本进行测试:
Autoit版本:
Func fibonacci($nn)
If $nn = 0 Then Return 0
If $nn <= 2 Then Return 1
return fibonacci($nn-1) + fibonacci($nn-2)
EndFunc
$testTimes = 20
$nn = 23
$totalTime = 0
$minTime = -1
$maxTime = -1
For $ii = 0 To $testTimes
$begin = TimerInit()
$result = fibonacci($nn)
$elapsed = TimerDiff($begin)
$totalTime += $elapsed
If $elapsed < $minTime Or $minTime = -1 Then $minTime = $elapsed
If $elapsed > $maxTime Then $maxTime = $elapsed
Next
$averageTime = $totalTime / $testTimes
MsgBox(0, "fibonacci", _
"fibonacci(" & $nn & ") =" & @TAB & $result & @CRLF & _
"testTimes:" & @TAB & $testTimes & @CRLF & _
"Average time:" & @TAB & $averageTime & @CRLF & _
"minTime:" & @TAB & $minTime & @CRLF & _
"maxTime:" & @TAB & $maxTime)
AutoHotkey版本:
fibonacci(nn)
- {
if ( 0 = nn )
return 0
if ( nn <= 2 )
return 1
return fibonacci(nn-1) + fibonacci(nn-2)
}
nn = 23
testTimes = 20
totalTime = 0
minTime = -1
maxTime = -1
Loop, % testTimes
- {
StartTime := A_TickCount
result := fibonacci(nn)
elapsed := A_TickCount - StartTime
totalTime += elapsed
If (elapsed < minTime Or minTime = -1)
minTime := elapsed
If (elapsed > maxTime)
maxTime := elapsed
}
averageTime := totalTime / testTimes
MsgBox, 0, fibonacci, fibonacci(%nn%) = %result%`ntestTimes = %testTimes%`nAverage:%averageTime%`nminTime:%minTime%`nmaxTime:%maxTime%
测试结果如下:
Autoit v3.3.0.0
fibonacci(23) = 28657
testTimes: 20
Average time: 522.569445485542
minTime: 466.840749850342
maxTime: 537.249004450691
AutoHotkey 1.0.48.03
fibonacci(23) = 28657
testTimes = 20
Average:668.750000
minTime:625
maxTime:719
测试平台:P4 3.06G
不过这也只是好玩而已,并没有太大的意义。
[Updated:2008-12-29]
修改了AHK的代码
增加了一段能在新版AU3中使用的代码
最简单的方法其实是先把要发送的内容先保存到剪贴板中去,然后在要发送的时候“粘贴”一下(Send一个 Ctrl+V)即可。不过这样做有一些缺点:
1、由于使用了剪贴板,用户在 Send 的过程中将不能正常使用 Ctrl+C 和 Ctrl+V 等剪贴板相关的功能;
2、有可能会在还没执行完“粘贴”操作之前剪贴板的内容就被修改了,结果发送了别的内容。
当然还有别的方法,先引用一下下面的内容:
我们通过键盘只能够输入键盘上有的字符,其实,按住 ALT 键,然后在数字键盘上按表示要输入字符的十进制代码值的键,等完成输入后,释放 ALT 键还可以输入键盘上没有的字符呢。
如果键入的第一个数字是“0”,该值将被识别为当前输入区域设置中的代码点或字符值。例如,在当前的输入区域设置为“英语(美国)”时(代码页 1252:Windows Latin-1),按住 ALT 键,然后在数字键盘上键入“0163”将产生英镑符号 £ (U+00A3)。在当前输入区域是 "Russia" (代码页 1251:Windows Cyrillic),相同的键顺序会产生西里尔大写字母 JE (U+040
。
而如果键入的第一位数是“1”到“9”的任意数,该值将被识别为系统 OEM 代码页中的代码点。根据在“控制面板”的“区域选项”中所指定的 Windows 系统区域设置,结果各有不同。例如,如果您的系统区域设置是“英语(美国)”,代码页为 437(MS-DOS 拉丁美洲),那么只要按住 ALT 键,然后在数字键盘上键入“163”,就可以输入 ú(U+00FA, 带重音符号的小写拉丁字母 U)。如果系统区域设置是“希腊语”(OEM 代码页 737 MS-DOS 希腊),相同序列将产生希腊语小写字母 MU (U+03BC)。
新建一个文本文件,输入“中文”这两个字并保存,然后用UltraEdit等十六进制编辑器打开并用十六进制视图显示,可看到如下内容:
00000000h: D6 D0 CE C4 ; 中文
可知中文这两个字的十六进制分别是 0xD6D0、0xCEC4(即十进制的54992、52932),那么如果要输入“中”字,则只要按住Alt键,逐个输入其十进制数字54992即可。
这样,要实现自己的 Send 函数就简单了:
AHK脚本:
; GBK是GB2312的扩展,是向下兼容的,因此GB2312中的汉字的编码与GBK中
; 汉字的相同。另外,GBK中还包含繁体字的编码,GBK中每个汉字仍然包含两
; 个字节,第一个字节的范围是0x81-0xFE(即129-254),第二个字节的范围
; 是0x40-0xFE(即64-254)。GBK中有码位23940个,包含汉字21003个。
#NoEnv
SetKeyDelay, 20 ; 如因速度过快导致发送不正常请尝试修改此行的延迟数值
SendMode InputThenPlay ; 如因速度过快导致发送不正常请则注释此行或改为其它模式
SetWorkingDir %A_ScriptDir%
string1 := "简体中文字符发送测试"
string2 := "繁體中文字符發送測試"
F10::
Loop, 100
{
SendString( "Sending #" . A_Index . " " . string1 )
Send, {Enter}
}
Return
SendString( string )
{
Len := StrLen(string) ; 得到字符串的长度,注意一个中文字符的长度是2,即占2个字节
Keys := "" ; 将要发送的字符序列
Index := 1 ; 用于循环
Loop
{
IsUnicodeChar := false
Code2 := 0 ; 字符2的ASCII码
Code1 := Asc( SubStr(string, Index, 1) ) ; 得到第一个字符的ASCII值
if(Code1 >= 129 && Code1 <= 254 && Index < Len) ; 判断是否中文字符的第一个字符
{
Code2 := Asc( SubStr(string, Index+1, 1) ) ; 得到第二个字符的ASCII值
if(Code2 >= 64 && Code2 <= 254) ; 若条件成立则说明是中文字符
{
IsUnicodeChar := true
Code1 <<= 8 ; 第一个字符应放到高8位上
Code1 += Code2 ; 第二个字符放在低8位上
}
++Index
}
if( IsUnicodeChar )
Keys .= "{ASC " . Code1 . "}"
else
{
Keys .= "{ASC 0" . Code1 . "}" ; 如果非中文字符,则需要前缀一个0
if( Code2 > 0 )
Keys .= "{ASC 0" . Code2 . "}"
}
++Index
if(Index > Len)
Break
}
Send % Keys
}
SendByClipboard( string, BackupClipBoard = false )
{
if(BackupClipBoard)
ClipSaved := ClipboardAll
ClipBoard := string
Send ^v
if(BackupClipBoard)
{
Clipboard := ClipSaved
ClipSaved =
}
}
///////////////////////////////////////////////////////////////////////////////
AU3脚本(3.2.4.0 之后的版本)
由于AutoIt自从版本3.2.4.0+开始已不再提供ANSI版本,因此再写个能在新版用的
测试版本:v3.3.0.0
在编写的过程中,一开始是打算使用 StringToBinary/Binary/DllStructSetData 来生成一个Ansi字符串方便处理的,但因为AutoIt存在将字符串截断的问题(这个问题也算是历史悠久了),因此不得不使用API来进行转换。
有意思的是,在AutoIt的更新日志里面却说这个问题已经解决了
:
Fixed #92: DllStruct data truncated with char[]/wchar[].
最后还是要抱怨一下默认情况下AutoIt的 Send 函数速度实在是太慢了,好在AutoHotkey的速度很理想,尽管Send这种功能我本来也很少用 ![]()
HotKeySet("{F10}", "SendTest")
While 1
Sleep(100)
WEnd
Func SendTest()
Local $string = "A中文字符串A"
$begin = TimerInit()
For $i = 1 To 10
_Send( $string )
Send("{Enter}")
Next
$dif = TimerDiff($begin)
MsgBox(0,"Time passed", $dif)
EndFunc
; 函数: _Send
; 用途:发送字符串
; 参数:$string,待转换的字符串,既可以是字符串字面值常量也可以是一个指向包含
; Unicode 字符数组的 DllStruct 元素的指针
; $bSendKeys,是否发送字符串,为 false 时只返回待发送的 Keys(请参考返回
; 值的说明) 而不发送字符串
; 返回值:使用 Send 函数时传递给它的第一个参数(Keys),形如 {Asc nn1}{Asc nn2}
Func _Send( Const $string, $bSendKeys = true )
Local $szKeys = "" ; 待发送的按键序列
Local $nLen = StringLen($string) ; 字符串的长度
; 字符串的 Unicode 编码数组
Local $UnicodeStringASCIIArray = StringToASCIIArray( $string )
; 因须将 $string 转换为多字节版本,下面计算足够用以保存转换成后数据的空间大小
Local $nAnsiBufferSize = ($nLen+1) * 2
; 用以保存转换后的结果
Local $pAnsiStringStruct = DllStructCreate("ubyte[" & $nAnsiBufferSize & "]")
; 将 $string 转换为多字节版本
Local $nBytesWritten = WideCharToMultiByte( $string, DllStructGetPtr($pAnsiStringStruct) )
If $nBytesWritten <= 0 Then
$pAnsiStringStruct = 0
Return SetError(@error, 0, "")
EndIf
Local $AnsiIndex = 1 ; Ansi 字符串元素的索引
Local $value ; 要传给 Send 函数的数值,用以构成 {Asc $value}
For $i = 0 To $nLen-1
$value = DllStructGetData($pAnsiStringStruct, 1, $AnsiIndex)
If $UnicodeStringASCIIArray[$i] > 255 Then ; 大于255的字符说明是Unicode字符
$AnsiIndex += 1
$value = $value * 256 + DllStructGetData($pAnsiStringStruct, 1, $AnsiIndex)
ElseIf $value > 0 Then
$value = "0" & $value
EndIf
$szKeys &= "{Asc " & $value & "}"
$AnsiIndex += 1
Next
If $bSendKeys Then Send($szKeys)
$pAnsiStringStruct = 0
Return $szKeys
EndFunc ;==>_Send
Func SendByClipboard( Const $string, $BackupClipBoard = false )
If $BackupClipBoard Then
Local $bak = ClipGet()
EndIf
ClipPut($string)
Send("^v")
If $BackupClipBoard Then ClipPut($bak)
EndFunc
; 函数: WideCharToMultiByte
; 用途:将 Unicode 字符串转换为多字节字符串
; 参数:$UnicodeString,待转换的字符串,既可以是字符串字面值常量也可以是一个指
; 向包含 Unicode 字符数组的 DllStruct 元素的指针
; $pMultiByte,用以保存转换结果的地址,指向一个char/byte数组的 DllStruct
; 元素的指针
; $iCodePage,代码页
; 返回值:写入到 $pMultiByte的字节数
Func WideCharToMultiByte($UnicodeString, $pMultiByte, $iCodePage = 0)
Local $aResult, $ParamType = "wstr"
If IsPtr($UnicodeString) Then $ParamType = "ptr"
$aResult = DllCall("Kernel32.dll", "int", "WideCharToMultiByte", "int", $iCodePage, "int", 0, _
$ParamType, $UnicodeString, "int", -1, "int", 0, "int", 0, "int", 0, "int", 0)
If @error Then Return SetError(@error, 0, 0)
$aResult = DllCall("Kernel32.dll", "int", "WideCharToMultiByte", "int", $iCodePage, "int", 0, _
$ParamType, $UnicodeString, "int", -1, "ptr", $pMultiByte, "int", $aResult[0], "int", 0, "int", 0)
If @error Then Return SetError(@error, 1, 0)
Return $aResult[0]
EndFunc ;==>WideCharToMultiByte
///////////////////////////////////////////////////////////////////////////////
AU3脚本(3.2.4.0 之前的版本)
(注意,最新版本(3.2.4.0+)已不再提供ANSI版本!因此请注意你的AutoIt版本):
#cs
运行脚本时需用 AutoIt3A.exe
将 AutoIt 目录下的AutoIt3A.exe重命名为AutoIt3.exe即可(建议先备份AutoIt3.exe)
编译脚本时需用 Aut2exeA.exe
#ce
Run("notepad")
WinWaitActive("[CLASS:Notepad]")
_SendRaw("简体中文And繁體中文")
Func _SendRaw($Keys)
Local $KeysInUnicode = ""
Local $len = StringLen($Keys)
Local $char1
Local $code1
Local $char2
Local $code2
Local $index = 1
While True
$code2 = 0
$char1 = StringMid($Keys, $index, 1)
$code1 = Asc($char1)
If $code1 >= 129 And $code1 <= 254 And $index < $len Then
$char2 = StringMid($Keys, $index+1, 1)
$code2 = Asc($char2)
If $code2 >= 64 And $code2 <= 254 Then
$code1 *= 256
$code1 += $code2
EndIf
$index += 1
EndIf
If $code1 <= 255 Then $code1 = "0" & $code1
$KeysInUnicode &= "{ASC " & $code1 & "}"
If $code2 > 0 And $code2 < 64 Then
$code2 = "0" & $code2
$KeysInUnicode &= "{ASC " & $code2 & "}"
EndIf
$index += 1
If $index > $len Then ExitLoop
WEnd
Send($KeysInUnicode)
EndFunc
关于在VC2005下编译AutoHotkey的方法其实在AHK的官方论坛上已经有相关帖子(点击此处查看)了,不过如果是在中文系统上编译还需要进行一点修改,由于可能会有人需要这方面的信息,因此以版本 1.0.47.06 为例说明一下,部分内容从上面提到的帖子中翻译而来。
AutoHotkey 源代码下载地址:
http://www.autohotkey.com/download/AutoHotkey104706_source.exe
1、下载源代码并解压,打开项目文件AutoHotkey.sln,由于AutoHotkey的源代码是在VC2003下建立的,因此需要进行转换;
2、转换完毕后直接编译,遇到一堆警告(主要都是叫你使用字符串函数的”安全“版本)和几个错误,到第一个错误的地方去看吧,提示是在文件 script.cpp 的第 1130 行处出错(主要是代码页产生的问题),该行内容如下:
if (strcmp(buf, "锘?)) // UTF-8 BOM marker is NOT present.
可看到上面这个字符串显示不正确,用UltraEdit等十六进制编辑工具打开 script.cpp 文件,到 1130 行并切换到十六进制显示方式,可知该字符串的十六进制表示是 EF BB BF (00),那么回到VC把这行改成如下所示即可:
if (strcmp(buf, "xEFxBBxBF")) // UTF-8 BOM marker is NOT present.
3、打开菜单 项目->AutoHotkey属性
a) 在 配置属性->C/C++->常规 下
把 将警告视为错误 设为 否
b) 在 配置属性->C/C++->预编译头 下
把 创建/使用预编译头 设为 创建预编译头(/Yc)
c) 在 配置属性->C/C++->高级 下
把 调用约定 改为其它项目后再改回 __cdecl (/Gd)
d) 在 配置属性->C/C++->高级 下
把 省略默认的库名称 设为 是(/Zl)
e) 在 配置属性->链接器->输入 下
把 忽略特定库 中的 LibCMT; 删除
f) 在 配置属性->链接器->优化 下
把 链接时间代码生成 设为 使用链接时间代码生成(/ltcg)
4、在VC的解决方案资源管理器中找到 AutoHotkey.rc 文件并选择 查看代码,找到
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "AutoHotkey.exe.manifest"
并注释该行
(该行代码的作用主要是让程序具有XP style,否则程序界面将以经典样式显示)
5、如果是Debug版本则无需做更多修改;如果是Release版本,需到 http://upx.sourceforge.net/ 下载UPX,把upx.exe放到项目所在文件夹(即AutoHotkey.sln的同一目录)下,目的是在编译成功后自动使用UPX压缩生成的可执行文件,当然也可以去掉这一步:在 项目->AutoHotkey属性 中,在 配置属性->生成事件->生成后事件 下把 命令行 中的内容 清空
6、开始编译,成功后VC将显示下述内容(Release版):
已完成传递 2
正在嵌入清单...
正在执行生成后事件...
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2008
UPX 3.03w Markus Oberhumer, Laszlo Molnar & John Reiser Apr 27th 2008
File size Ratio Format Name
-------------------- ------ ----------- -----------
536576 -> 254976 47.52% win32/pe AutoHotkey.exe
Packed 1 file.
生成日志保存在“file://e:Code4FunAutoHotkey104706_sourceReleaseBuildLog.htm”
AutoHotkey - 0 个错误,16 个警告
========== 生成: 1 已成功, 0 已失败, 1 最新, 0 已跳过 ==========
今晚既然有空就一并将上次发现的一些问题给解决掉吧,更新如下:
1)使用多线程,刚开始打开进程列表对话框时不会停顿了;
2)修正了在进程列表排序后选中某个进程时DLL更新错误的BUG;
3)修正了在进程列表排序后使用窗口/进程查找工具时定位进程项目错误的BUG;
下载地址:
下载地址1 备用下载地址
MD5: 1367D3319D2034957FEF3A9C0DBAD9FF
[注意:这篇文章不是讲脚本的]
这是一个用来向指定进程注入代码/DLL的小工具,简单点说就是让某个进程执行你想让它执行的指令,或是让这个进程加载你/别人写的DLL模块,知道plugin的人应该很容易了解这是什么意思,暂时来说使用这个工具的人需要了解一定的汇编语言知识和Windows的进程/DLL机制。
这个小工具其实是2月份的时候就写了一半了,虽然并没能完成我当初想要实现的全部功能,却因为各种原因也没办法继续写下去了,但毕竟算是有点小实用性的功能出来了,就在广海论坛上发布过,当时还算挺受欢迎的。后来经过断断续续的修改,觉得也发布出来让有需要的人用一下。
主要是有了下面的一些变化:
[-] 把反汇编引擎的DLL去掉,直接整合到主程序中;
[+] 增加了DLL的注入/卸载等功能;
[*] 在对进程列表进行排序的时候,不再重新遍历进程,速度正常了,不再像之前那样要卡一下。
开发工具:Microsoft Visual Studio 6.0
先看看主界面:
主窗口(图一)

了解的人看了上图一眼应该就很容易知道怎么用了,但为了尽可能让更多的人了解,还是以一个实例来说一下吧!
实例目标:Windows自带的计算器(Calc.exe)
实例任务:让计算器自己弹出一个对话框,标题是"Test",内容是"Hello!"
实例分析:
[Q] 怎么弹出对话框?
[A] 弹出对话框需要调用API(可理解为操作系统提供给我们使用的函数/代码)MessageBox,其原型为:
int MessageBox(
HWND hWnd, // 父窗口的句柄
LPCTSTR lpText, // 对话框的正文
LPCTSTR lpCaption, // 对话框的标题
UINT uType // 对话框的类型
);
其中hWnd和uType我们暂时不用管是什么意思,只需要知道hWnd我们传个0给它就好了,而uType倒可以随便传个数字看看结果有什么不一样,另外两个参数想必也毋庸多说了吧。
在这个任务中,如果用的是C/C++,我们应该这样调用:
MessageBox(0, "Hello!", "Test", 123);
但我们在CodeInjector中用的是纯汇编,要调用函数就需要类似这样的代码:
push 参数2
push 参数1
call 函数地址
但这里首先遇到了个问题:CodeInjector暂时还不支持定义变量/标号/过程等!也就是说,我们要的"Hello"和"Test"要另外想办法制造出来。我想到的办法是利用堆栈,我们先来看看"Hello"和"Test"在内存中应该是怎么的一个样子:
54 65 73 74 00 48 65 6C 6C 6F 21 00 ==> Test Hello!
这是这两个字符串(刚好12个字节)连在一起存放的情况,左侧是每个字符的ASCII码(十六进制),在C/C++中字符串是以0作为结束标志的。
好了,我们想象一下它们在堆栈中的存放情况:
54 65 73 74 | Test <- esp,栈顶
00 48 65 6C | Hel
6C 6F 21 00 | lo!
如果我们紧接着就开始把参数压栈的话,那接下来堆栈的内容应该是这样的:
uType
lpCaption -> esp
lpText -> esp+5
hWnd
[Q] 怎么解决MessageBox的地址问题
[A] 利用调试器即可,此略。
实例步骤:
一、运行计算器
二、运行CodeInjector(点此下载)
三、点击主窗口(见图一)左上方的按钮“选择目标进程”,在弹出窗口(见下图)上方的进程列表中选中计算器的进程并点击“确定”按钮:
(图二)

四、利用调试器或其它方法确定MessageBoxA的地址,假设为0x77D507EA(注意,这个值因系统而异);
五、回到主窗口,在中间的编辑框中输入以下代码:
; 54 65 73 74 00 48 65 6C 6C 6F 21 00 ==> Test Hello!
; Stack should be the following:
; 54 65 73 74 | Test <- esp
; 00 48 65 6C | Hel
; 6C 6F 21 00 | lo!
; uType
; lpCaption -> esp
; lpText -> esp+5
; hWnd
push 0x00216F6C
push 0x6C654800
push 0x74736554
push eax ; save eax
mov eax, esp
add eax, 4 ; eax -> lpCaption
push 0x00010040 ; uType
push eax ; lpCaption
add eax, 5
push eax ; lpText
push 0 ; hWnd
call 0x77D507EA ; MessageBoxA (注意,这个地址因系统而异)
pop eax ; restore eax
add esp, 0xC
六、点击主窗口上的“CreateRemoteThread”按钮。
实例结果:
在点击“CreateRemoteThread”按钮后,会发现弹出一个对话框,如下图所示:
(图三)

该对话框的标题和内容完全如目标一致,而且注意它的图标,跟计算器的一样,说明两者属于同一进程,任务成功。
至于DLL注入的部分因为简单在此就不多做介绍了。
关于注入代码的部分,本来我的计划是不用汇编,而是以一种能实现语言基本功能的“脚本”的方式,比如支持变量等,但因时间关系暂时还没办法做,有机会再说吧。
----------------------------------------------------------------
转载请注明来自 http://yonken.blogcn.com
CodeInjector下载:点击此处
备用下载地址:http://www.namipan.com/d/7cf9f3fee75511432cffcafba055d24ae5e3fdd000de0200
MD5: C49999C3E3B2E1DFA7EFF71BDB574B44
----------------------------------------------------------------