﻿﻿
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>雨律在线 &#187; 学习编程</title>
	<atom:link href="http://yulv.net/archives/category/%e5%ad%a6%e4%b9%a0%e7%bc%96%e7%a8%8b/feed" rel="self" type="application/rss+xml" />
	<link>http://yulv.net</link>
	<description>魔兽改键官方网站</description>
	<lastBuildDate>Wed, 14 Sep 2022 02:14:42 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>BR TH</title>
		<link>http://yulv.net/archives/519</link>
		<comments>http://yulv.net/archives/519#comments</comments>
		<pubDate>Fri, 20 Nov 2009 07:54:18 +0000</pubDate>
		<dc:creator>JiaJia</dc:creator>
				<category><![CDATA[学习编程]]></category>
		<category><![CDATA[ManaBars]]></category>
		<category><![CDATA[WarKey]]></category>
		<category><![CDATA[WarMP]]></category>
		<category><![CDATA[显蓝]]></category>
		<category><![CDATA[魔兽改键伴侣]]></category>

		<guid isPermaLink="false">http://yulv.net/archives/519</guid>
		<description><![CDATA[VS终结者原理简要说明： VS检测作弊肯定不会放在主线程，既然是另开线程，那就好办的多，用procexp等工具 [...]]]></description>
				<content:encoded><![CDATA[<p>VS终结者原理简要说明：</p>
<p>VS检测作弊肯定不会放在主线程，既然是另开线程，那就好办的多，用procexp等工具查看一下VS的线程信息（用HideToolz隐藏，不然会被关闭），通过观察找到入手点，找到线程启动地址以后，分析就好办的多了...</p>
<p>Sleep掉VS反作弊模块的线程，在线程中间函数（VS 3.12 地址：0x0045f640&nbsp; VS3.0 地址：0x0045f782）处HOOK，判断传入地址，如果为检测反作弊的函数地址则 while(1) Sleep(10000);，作用一看就明白了，线程不能retn ，不然VS会退出...</p>
<p>至于哪些函数是检测作弊的，这个也容易找到，搜索字符串&ldquo;作弊&rdquo;，搜索ReadProcessMemory，还有因为通过线程中间函数启动的只有12个线程，先HOOK一下，得到这12个函数入口地址，缩小范围在这12个函数里面找...</p>
<p>还有说明一下：有一个线程不能简单Sleep，不然启动魔兽1分钟左右就会掉线，所以只能在这个函数中nop掉调用检测函数的代码...</p>
<p>=======================================================================</p>
<p><strong>VS 3.12</strong></p>
<p>0040139D</p>
<p>004016DB</p>
<p>004030F8</p>
<p>00401807</p>
<p>004031A2</p>
<p>004047C3</p>
<p>004039C2</p>
<p>上面7个函数Sleep掉</p>
<p>入口地址为0404B3D的函数，在0045B4D6处NOP五个字节</p>
<p>=======================================================================</p>
<p><strong>VS3.0</strong></p>
<p>004016CC</p>
<p>004017F3</p>
<p>00401389</p>
<p>00403125</p>
<p>004047DC</p>
<p>004031CF</p>
<p>004039E5</p>
<p>上面7个函数Sleep掉</p>
<p>入口地址为00404B5B的函数，在0045B618出NOP五个字节</p>
<p>=======================================================================</p>
<p>把原理交待了我就可以安心潜水了，上面虽然是简要说明，但是只要是研究过VS反作弊的朋友一眼就能看懂，只要VS小规模更新，稍微改下代码就行了...</p>
<p>只是希望继续破解之路的朋友能免费下去，也不多说了，每个人的出发点不一样毕竟...</p>
<p>顺便说一下，我喜欢用OD直接在内存上写汇编代码（OD的汇编功能非常强大），写好后再拷贝出16进制数值，用程序WriteProcessMemory写进去，这样方便感觉很舒服...&nbsp;&nbsp;顺便贴一下我写的汇编代码，很简单的几行...</p>
<p>以VS3.12为例：</p>
<table style="width: 358px; height: 129px" border="1" cellspacing="1" cellpadding="1" width="358">
<tbody>
<tr>
<td>
<p>0045F640&nbsp; /.&nbsp; 55&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp; ebp<br />            0045F641&nbsp; |.&nbsp; 8BEC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebp, esp<br />            0045F643&nbsp; |.&nbsp; 51&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp; ecx<br />            0045F644&nbsp; |.&nbsp; 51&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp; ecx<br />            0045F645&nbsp; |.&nbsp; 6A 08&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;push&nbsp;&nbsp;&nbsp; 8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #999999">; /n = 8<br />            </span>0045F647&nbsp; |.&nbsp; 8D45 F8&nbsp;&nbsp;&nbsp;lea&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;eax, dword ptr [ebp-8]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #999999">; |</span></p>
</td>
</tr>
</tbody>
</table>
<p>入口处JMP走&nbsp;&nbsp;改为：</p>
<table style="width: 529px; height: 570px" border="1" cellspacing="1" cellpadding="1" width="529">
<tbody>
<tr>
<td>
<p>0045F640&nbsp; ^\E9 B3FCFFFF&nbsp;&nbsp;&nbsp;&nbsp; jmp&nbsp;&nbsp;&nbsp;&nbsp; 0045F2F8<br />            0045F645&nbsp;&nbsp;&nbsp; 6A 08&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp; 8</p>
<p>0045F2F6&nbsp;&nbsp;&nbsp; CC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int3<br />            0045F2F7&nbsp;&nbsp;&nbsp; CC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int3<br />            0045F2F8&nbsp;&nbsp;&nbsp; 8B5C24 04&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp; ebx, dword ptr [esp+4]<br />            0045F2FC&nbsp;&nbsp;&nbsp; 8B03&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp; eax, dword ptr [ebx]<br />            0045F2FE&nbsp;&nbsp;&nbsp; 3D 9D134000&nbsp;&nbsp;&nbsp;&nbsp; cmp&nbsp;&nbsp;&nbsp;&nbsp; eax, 0040139D&nbsp;&nbsp;&nbsp;<span style="color: #999999">;比较函数地址&nbsp; 是 就 JMP到Sleep处</span>&nbsp;&nbsp; <br />            0045F303&nbsp;&nbsp;&nbsp; 74 34&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; je&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; short 0045F339&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />            0045F305&nbsp;&nbsp;&nbsp; 3D DB164000&nbsp;&nbsp;&nbsp;&nbsp; cmp&nbsp;&nbsp;&nbsp;&nbsp; eax, 004016DB<br />            0045F30A&nbsp;&nbsp;&nbsp; 74 2D&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; je&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; short 0045F339<br />            0045F30C&nbsp;&nbsp;&nbsp; 3D F8304000&nbsp;&nbsp;&nbsp;&nbsp; cmp&nbsp;&nbsp;&nbsp;&nbsp; eax, 004030F8<br />            0045F311&nbsp;&nbsp;&nbsp; 74 26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; je&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; short 0045F339<br />            0045F313&nbsp;&nbsp;&nbsp; 3D 07184000&nbsp;&nbsp;&nbsp;&nbsp; cmp&nbsp;&nbsp;&nbsp;&nbsp; eax, 00401807<br />            0045F318&nbsp;&nbsp;&nbsp; 74 1F&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; je&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; short 0045F339<br />            0045F31A&nbsp;&nbsp;&nbsp; 3D C3474000&nbsp;&nbsp;&nbsp;&nbsp; cmp&nbsp;&nbsp;&nbsp;&nbsp; eax, 004047C3<br />            0045F31F&nbsp;&nbsp;&nbsp; 74 18&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; je&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; short 0045F339<br />            0045F321&nbsp;&nbsp;&nbsp; 3D C2394000&nbsp;&nbsp;&nbsp;&nbsp; cmp&nbsp;&nbsp;&nbsp;&nbsp; eax, 004039C2<br />            0045F326&nbsp;&nbsp;&nbsp; 74 11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; je&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; short 0045F339<br />            0045F328&nbsp;&nbsp;&nbsp; 3D A2314000&nbsp;&nbsp;&nbsp;&nbsp; cmp&nbsp;&nbsp;&nbsp;&nbsp; eax, 004031A2<br />            0045F32D&nbsp;&nbsp;&nbsp; 74 0A&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; je&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; short 0045F339<br />            0045F32F&nbsp;&nbsp;&nbsp; 55&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp; ebp<br />            0045F330&nbsp;&nbsp;&nbsp; 8BEC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp; ebp, esp<br />            0045F332&nbsp;&nbsp;&nbsp; 51&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp; ecx<br />            0045F333&nbsp;&nbsp;&nbsp; 51&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp; ecx<br />            0045F334&nbsp;&nbsp;&nbsp; E9 0C030000&nbsp;&nbsp;&nbsp;&nbsp; jmp&nbsp;&nbsp;&nbsp;&nbsp; 0045F645&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #999999">;JMP 回&nbsp; push 8 处</span> <br />            0045F339&nbsp;&nbsp;&nbsp; 68 10270000&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp; 2710&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #999999">;Sleep</span> <br />            0045F33E&nbsp;&nbsp;&nbsp; FF15 606E5600&nbsp;&nbsp; call&nbsp;&nbsp;&nbsp; dword ptr [566E60]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #999999">; kernel32.Sleep</span> <br />            0045F344&nbsp; ^ EB F3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jmp&nbsp;&nbsp;&nbsp;&nbsp; short 0045F339&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #999999">;JMP 到Sleep&nbsp;</span></p>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://yulv.net/archives/519/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Code StuCE</title>
		<link>http://yulv.net/archives/517</link>
		<comments>http://yulv.net/archives/517#comments</comments>
		<pubDate>Wed, 07 Oct 2009 16:18:48 +0000</pubDate>
		<dc:creator>JiaJia</dc:creator>
				<category><![CDATA[学习编程]]></category>
		<category><![CDATA[ManaBars]]></category>
		<category><![CDATA[WarMP]]></category>
		<category><![CDATA[WarZxx]]></category>
		<category><![CDATA[WZVIP]]></category>
		<category><![CDATA[显蓝]]></category>
		<category><![CDATA[魔兽最强兵器]]></category>

		<guid isPermaLink="false">http://yulv.net/archives/517</guid>
		<description><![CDATA[关于aobscan的实现原理
]]></description>
				<content:encoded><![CDATA[<p>关于aobscan的实现原理<br/><br/>我发现这里好多人用的语言都不一样，所以我尽量就不针对某种语言来讲了。（我写的C代码）<br/><br/>首先，获得进程PID。<br/>可以根据标题获得，也可以根据进程名获得。各有各的好处吧。还有窗口类名哈。<br/><br/>例如：<br/>        HWND hwnd = FindWindow("MainWindow", NULL);<br/>        if (hwnd)<br/>        {<br/>                DWORD dwPid;<br/>                GetWindowThreadProcessId(hwnd, &#038;dwPid);<br/>                //return dwPid;<br/>        }<br/><br/>第二步，获得进程相关信息，例如内存大小。<br/><br/>        HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);<br/>        PROCESS_MEMORY_COUNTERS pmc;<br/>        pmc.cb = sizeof(PROCESS_MEMORY_COUNTERS);<br/>        ::GetProcessMemoryInfo( hProcess, &#038;pmc, sizeof(pmc));<br/>        //printf("%d\n%d\n",dwPid,pmc.WorkingSetSize/1024/1024);<br/><br/>第三步，遍历程序内存。<br/>因为上一步已经获得内存大小了，所以一个循环。<br/>(获得内存数据之前，是否检查一下内存属性呢？我觉得应该需要，但是我这里只讲讲原理，就省掉了)<br/>另外据说Windows一个内存页就是4kb，所以写成这样：<br/><br/>        char key[] = {0x80, 0x7f, 0x49, 0x00};//查找的数据以及长度<br/>        int len = 4;        <br/>        PBYTE pAddress = NULL;<br/>        int i = 0;<br/>        int n = 0;<br/>        for (; i < pmc.WorkingSetSize; i += 4096)<br/>        {<br/>                BYTE arBytes[4096];<br/>                if (!::ReadProcessMemory(hProcess, (LPVOID)i, arBytes, 4096, NULL)) continue;<br/>                {<br/>                        if (memstr(key, len, (char*)arBytes, 4096) != 0)<br/>                        {<br/>                                printf("%d  %d\n", memstr(key, len, (char*)arBytes, 4096), arBytes);<br/>                                n = memstr(key, len, (char*)arBytes, 4096) - (unsigned char*)arBytes;<br/>                                break;<br/>                        }<br/>                }<br/>        }<br/>        i += n;<br/>        printf("%x  %d", i, n);<br/><br/>现在i变量中的地址，就是我们查找的数据的地址了。<br/><br/><br/>附带一个最简单的menstr函数，几乎没有优化哈。<br/><br/>unsigned char *memstr(char * dst , int dst_len, char *src , int src_len )<br/>{<br/>        int i;<br/>        char *cp = src;<br/>        if (src_len < dst_len)<br/>        {<br/>                return NULL;<br/>        }<br/>        for (i = 0; i <= src_len - dst_len; i++)<br/>        {<br/>                if (memcmp(cp , dst , dst_len) == 0)<br/>                {<br/>                        return (unsigned char *)cp;<br/>                }<br/>                cp++;<br/>        }<br/>        return   NULL;<br/>}</p>
]]></content:encoded>
			<wfw:commentRss>http://yulv.net/archives/517/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Code CE</title>
		<link>http://yulv.net/archives/516</link>
		<comments>http://yulv.net/archives/516#comments</comments>
		<pubDate>Wed, 07 Oct 2009 16:16:21 +0000</pubDate>
		<dc:creator>JiaJia</dc:creator>
				<category><![CDATA[学习编程]]></category>
		<category><![CDATA[360误报]]></category>
		<category><![CDATA[WarKey]]></category>

		<guid isPermaLink="false">http://yulv.net/archives/516</guid>
		<description><![CDATA[C++实现的完整aobscan，速度很快，貌似有点Bug，需要修正。<br/>完整的aobscan实现，我在搜索部分使用了一个高速搜索算法。
]]></description>
				<content:encoded><![CDATA[<p>C++实现的完整aobscan，速度很快，貌似有点Bug，需要修正。<br/>完整的aobscan实现，我在搜索部分使用了一个高速搜索算法。<br/><br/><br/>#include <windows.h><br/>#include <Psapi.h>#include <stdio.h><br/>#include <time.h><br/><br/>/*这是一个很低效的算法*/<br/>unsigned char *memstr(char * dst , int dst_len, char *src , int src_len )<br/>{<br/>    int i;<br/>    char *cp = src;<br/>    if (src_len < dst_len)<br/>    {<br/>        return NULL;<br/>    }<br/>    for (i = 0; i <= src_len - dst_len; i++)<br/>    {<br/>        if (memcmp(cp , dst , dst_len) == 0)<br/>        {<br/>            return (unsigned char *)cp;<br/>        }<br/>        cp++;<br/>    }<br/>    return   NULL;<br/>}<br/><br/>/*sunday算法*/<br/>#define MAX_CHAR_SIZE 257<br/>long *setCharStep(const unsigned char *subStr, long subStrLen)<br/>{<br/>    long i;<br/>    static long charStep[MAX_CHAR_SIZE];<br/>    for (i = 0; i < MAX_CHAR_SIZE; i++)<br/>        charStep[i] = subStrLen + 1;<br/>    for (i = 0; i < subStrLen; i++)<br/>    {<br/>        charStep[(unsigned char)subStr[i]] = subStrLen - i;<br/>    }<br/>    return charStep;<br/>}<br/>/*<br/>   算法核心思想，从左向右匹配，遇到不匹配的看大串中匹配范围之外的右侧第一个字符在小串中的最右位置<br/>   根据事先计算好的移动步长移动大串指针，直到匹配<br/>*/<br/>long sundaySearch(const unsigned char *mainStr, const unsigned char *subStr, long *charStep, long mainStrLen, int subStrLen)<br/>{<br/>    long main_i = 0;<br/>    long sub_j = 0;<br/>    while (main_i < mainStrLen)<br/>    {<br/>        //保存大串每次开始匹配的起始位置，便于移动指针<br/>        long tem = main_i;<br/>        while (sub_j < subStrLen)<br/>        {<br/>            if (mainStr[main_i] == subStr[sub_j])<br/>            {<br/>                main_i++;<br/>                sub_j++;<br/>                continue;<br/>            }<br/>            else<br/>            {<br/>                //如果匹配范围外已经找不到右侧第一个字符，则匹配失败<br/>                if (tem + subStrLen > mainStrLen)<br/>                    return -1;<br/>                //否则 移动步长 重新匹配<br/>                unsigned char firstRightChar = mainStr[tem + subStrLen];<br/>                main_i += charStep[(unsigned char)firstRightChar];<br/>                sub_j = 0;<br/>                break; //退出本次失败匹配 重新一轮匹配<br/>            }<br/>        }<br/>        if (sub_j == subStrLen)<br/>            return main_i - subStrLen;<br/>    }<br/>    return -1;<br/>}<br/><br/>unsigned char getHex(unsigned char hex)<br/>{<br/>    if (hex >= '0' &#038;& hex <= '9') return hex - '0';<br/>    if (hex >= 'A' &#038;& hex <= 'F') return hex - 'A' + 10;<br/>    if (hex >= 'a' &#038;& hex <= 'f') return hex - 'a' + 10;<br/>    return 0;<br/>}<br/>int GetHexValue(char *src)<br/>{<br/>    int i, j, flag;<br/>    static char temp[1024];<br/>    for (i = 0, j = 0; src[i] != 0; i++)<br/>    {<br/>        if ((src[i] <= 'F' &#038;& src[i] >= 'A') || (src[i] <= 'f' &#038;& src[i] >= 'a') || (src[i] <= '9' &#038;& src[i] >= '0'))<br/>        {<br/>            if (src[i] != ' ')<br/>            {<br/>                temp[j++] = src[i];<br/>            }<br/>        }<br/>    }<br/>    temp[j] = 0;<br/>    src[0] = 0;<br/>    for (i = 0, j = 0, flag = 1; temp[i] != 0; i++)<br/>    {<br/><br/>        char ch = getHex(temp[i]);<br/>        if (ch != -1)<br/>        {<br/>            if (flag == 1) src[j] = ch << 4;<br/>            else src[j++] += ch;<br/>            flag *= -1;<br/>        }<br/>    }<br/>    src[j] = 0;<br/>    return j;<br/>}<br/>DWORD ReadPage(HANDLE m_hProcess, DWORD dwBaseAddr, char* Value)<br/>{<br/>    //读取1页内存<br/>    BYTE arBytes[4096];<br/>    if (!::ReadProcessMemory(m_hProcess, (LPVOID)dwBaseAddr, arBytes, 4096, NULL))<br/>    {<br/>        //此页不可读<br/>        return (DWORD) - 1;<br/>    }<br/>    else<br/>    {<br/>        //<br/>        //unsigned char key[] = {0x80, 0x7f, 0x49, 0x00};<br/>        unsigned char Value2[1024];<br/>        strcpy((char*)Value2, Value);<br/>        int len = GetHexValue((char*)Value2);<br/>        //getchar();<br/>        //注释这两行是低效的算法<br/>        //char key[] = {0x80, 0x7f, 0x49, 0x00};<br/>        //int len = 4;<br/>        //if (memstr(key, len, (char*)arBytes, 4096) != 0) return memstr(key, len, (char*)arBytes, 4096) - (unsigned char*)arBytes;<br/>        //else return -1;<br/><br/>        //开始sunday算法<br/>        long *charStep = setCharStep(Value2, len);<br/>        return sundaySearch(arBytes, Value2, charStep, 4096, len);<br/>    }<br/>    return (DWORD) - 1;    //不会执行到此处<br/>}<br/><br/>DWORD aobscan(DWORD dwPid, char* Value)<br/>{<br/>    if (dwPid == 0) return (DWORD) - 1;<br/><br/>    HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);<br/>    if (hProcess != NULL)<br/>    {<br/>        //获得内存大小<br/>        PROCESS_MEMORY_COUNTERS pmc;<br/>        pmc.cb = sizeof(PROCESS_MEMORY_COUNTERS);<br/>        ::GetProcessMemoryInfo( hProcess, &#038;pmc, sizeof(pmc));<br/><br/>        //遍历内存<br/>        for (int i = 0; i < pmc.WorkingSetSize; i += 4096)<br/>        {<br/>            DWORD dwValue = ReadPage(hProcess, i, Value);<br/>            if (dwValue != -1)<br/>            {<br/>                printf("Found:0x%X\n", i + dwValue);<br/>                return i + dwValue;<br/>            }<br/>        }<br/>        ::CloseHandle(hProcess);<br/>    }<br/>    printf("Nothing Found!\n");<br/>    return (DWORD) - 1;<br/>}<br/>DWORD GetGameID()<br/>{<br/>    HWND hwnd = FindWindow("MainWindow", NULL);<br/>    if (hwnd)<br/>    {<br/>        DWORD dwPid;<br/>        GetWindowThreadProcessId(hwnd, &#038;dwPid);<br/>        return dwPid;<br/>    }<br/>    return 0;<br/>}<br/>int main()<br/>{<br/>    double begin = clock();<br/><br/>    aobscan(GetGameID(), "807f49 00");<br/><br/>    printf("time:%.0fms", clock() - begin);<br/>    getchar();<br/>}</p>
]]></content:encoded>
			<wfw:commentRss>http://yulv.net/archives/516/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Code CE</title>
		<link>http://yulv.net/archives/515</link>
		<comments>http://yulv.net/archives/515#comments</comments>
		<pubDate>Wed, 07 Oct 2009 16:11:16 +0000</pubDate>
		<dc:creator>JiaJia</dc:creator>
				<category><![CDATA[学习编程]]></category>
		<category><![CDATA[WarHelper]]></category>
		<category><![CDATA[加加魔兽助手]]></category>
		<category><![CDATA[魔兽改键助手]]></category>

		<guid isPermaLink="false">http://yulv.net/archives/515</guid>
		<description><![CDATA[VB实现CE的AobScan功能,仿CE字节组内存搜索.
]]></description>
				<content:encoded><![CDATA[<p>VB实现CE的AobScan功能,仿CE字节组内存搜索.<br/><br/><textarea class="code" rows="10" cols="50">'这里的东西写模块里面，具体怎么写，我不告诉你<br />
Private&nbsp;Declare&nbsp;Function&nbsp;GetWindowThreadProcessId&nbsp;Lib&nbsp;"user32"&nbsp;(ByVal&nbsp;hwnd&nbsp;As&nbsp;Long,&nbsp;lpdwProcessId&nbsp;As&nbsp;Long)&nbsp;As&nbsp;Long<br />
Private&nbsp;Declare&nbsp;Function&nbsp;FindWindow&nbsp;Lib&nbsp;"user32"&nbsp;Alias&nbsp;"FindWindowA"&nbsp;(ByVal&nbsp;lpClassName&nbsp;As&nbsp;String,&nbsp;ByVal&nbsp;lpWindowName&nbsp;As&nbsp;String)&nbsp;As&nbsp;Long<br />
Public&nbsp;Declare&nbsp;Function&nbsp;OpenProcess&nbsp;Lib&nbsp;"kernel32"&nbsp;(ByVal&nbsp;dwDesiredAccess&nbsp;As&nbsp;Long,&nbsp;ByVal&nbsp;bInheritHandle&nbsp;As&nbsp;Long,&nbsp;ByVal&nbsp;dwProcessId&nbsp;As&nbsp;Long)&nbsp;As&nbsp;Long<br />
Private&nbsp;Declare&nbsp;Function&nbsp;GetProcessMemoryInfo&nbsp;Lib&nbsp;"PSAPI.DLL"&nbsp;(ByVal&nbsp;hProcess&nbsp;As&nbsp;Long,&nbsp;ppsmemCounters&nbsp;As&nbsp;PROCESS_MEMORY_COUNTERS,&nbsp;ByVal&nbsp;cb&nbsp;As&nbsp;Long)&nbsp;As&nbsp;Long<br />
Public&nbsp;Declare&nbsp;Function&nbsp;CloseHandle&nbsp;Lib&nbsp;"kernel32"&nbsp;(ByVal&nbsp;hObject&nbsp;As&nbsp;Long)&nbsp;As&nbsp;Long<br />
Public&nbsp;Declare&nbsp;Function&nbsp;VirtualQueryEx&nbsp;Lib&nbsp;"kernel32"&nbsp;(ByVal&nbsp;hProcess&nbsp;As&nbsp;Long,&nbsp;ByVal&nbsp;lpAddress&nbsp;As&nbsp;Long,&nbsp;lpBuffer&nbsp;As&nbsp;MEMORY_BASIC_INFORMATION,&nbsp;ByVal&nbsp;dwLength&nbsp;As&nbsp;Long)&nbsp;As&nbsp;Long<br />
Public&nbsp;Declare&nbsp;Function&nbsp;ReadProcessMemory&nbsp;Lib&nbsp;"kernel32"&nbsp;(ByVal&nbsp;hProcess&nbsp;As&nbsp;Long,&nbsp;ByVal&nbsp;lpBaseAddress&nbsp;As&nbsp;Any,&nbsp;lpBuffer&nbsp;As&nbsp;Any,&nbsp;ByVal&nbsp;nSize&nbsp;As&nbsp;Long,&nbsp;lpNumberOfBytesWritten&nbsp;As&nbsp;Long)&nbsp;As&nbsp;Long<br />
Public&nbsp;Type&nbsp;MEMORY_BASIC_INFORMATION<br />
BaseAddress&nbsp;As&nbsp;Long<br />
AllocationBase&nbsp;As&nbsp;Long<br />
AllocationProtect&nbsp;As&nbsp;Long<br />
RegionSize&nbsp;As&nbsp;Long<br />
State&nbsp;As&nbsp;Long<br />
Protect&nbsp;As&nbsp;Long<br />
lType&nbsp;As&nbsp;Long<br />
End&nbsp;Type<br />
Type&nbsp;PROCESS_MEMORY_COUNTERS<br />
cb&nbsp;As&nbsp;Long<br />
PageFaultCount&nbsp;As&nbsp;Long<br />
PeakWorkingSetSize&nbsp;As&nbsp;Long<br />
WorkingSetSize&nbsp;As&nbsp;Long<br />
QuotaPeakPagedPoolUsage&nbsp;As&nbsp;Long<br />
QuotaPagedPoolUsage&nbsp;As&nbsp;Long<br />
QuotaPeakNonPagedPoolUsage&nbsp;As&nbsp;Long<br />
QuotaNonPagedPoolUsage&nbsp;As&nbsp;Long<br />
PagefileUsage&nbsp;As&nbsp;Long<br />
PeakPagefileUsage&nbsp;As&nbsp;Long<br />
End&nbsp;Type<br />
Public&nbsp;Function&nbsp;GetPid(lpClassName&nbsp;As&nbsp;String,&nbsp;lpWindowName&nbsp;As&nbsp;String)&nbsp;As&nbsp;Long<br />
GetWindowThreadProcessId&nbsp;FindWindow(lpClassName,&nbsp;lpWindowName),&nbsp;GetPid<br />
End&nbsp;Function<br />
Public&nbsp;Function&nbsp;GetMemoryByPID(ByVal&nbsp;Pid&nbsp;As&nbsp;Integer)&nbsp;As&nbsp;String<br />
Dim&nbsp;tPMC&nbsp;As&nbsp;PROCESS_MEMORY_COUNTERS<br />
Dim&nbsp;lProcessID<br />
Dim&nbsp;hProcess<br />
lProcessID&nbsp;=&nbsp;Pid<br />
hProcess&nbsp;=&nbsp;OpenProcess(&#038;H1F0FFF,&nbsp;False,&nbsp;lProcessID)<br />
If&nbsp;(GetProcessMemoryInfo(hProcess,&nbsp;tPMC,&nbsp;Len(tPMC))&nbsp;&lt;&gt;&nbsp;0)&nbsp;Then<br />
GetMemoryByPID&nbsp;=&nbsp;Hex(tPMC.WorkingSetSize)<br />
End&nbsp;If<br />
CloseHandle&nbsp;hProcess<br />
End&nbsp;Function</textarea><br/><br/><textarea class="code" rows="10" cols="50">'程序窗体定义一个局部变量<br />
Dim&nbsp;GamePid&nbsp;As&nbsp;String<br />
Dim&nbsp;Rst(2000000)&nbsp;As&nbsp;Long<br />
Private&nbsp;Sub&nbsp;Form_Load()<br />
GamePid&nbsp;=&nbsp;GetPid(vbNullString,&nbsp;"程序名写到这里，你知道的！")<br />
End&nbsp;Sub<br />
'把字节数组转换的函数<br />
Function&nbsp;Fz(Str&nbsp;As&nbsp;String)&nbsp;As&nbsp;String<br />
Dim&nbsp;a&nbsp;As&nbsp;String<br />
a&nbsp;=&nbsp;Replace(Str,&nbsp;"&nbsp;",&nbsp;"")<br />
Dim&nbsp;i&nbsp;As&nbsp;Integer<br />
Dim&nbsp;b&nbsp;As&nbsp;String<br />
For&nbsp;i&nbsp;=&nbsp;Len(a)&nbsp;To&nbsp;2&nbsp;Step&nbsp;-2<br />
b&nbsp;=&nbsp;b&nbsp;&&nbsp;Mid(a,&nbsp;i&nbsp;-&nbsp;1,&nbsp;2)<br />
Next<br />
Fz&nbsp;=&nbsp;b<br />
End&nbsp;Function</textarea><br/><br/><textarea class="code" rows="10" cols="50">Function&nbsp;AobScan(Pid&nbsp;As&nbsp;String,&nbsp;ZJSZ&nbsp;As&nbsp;String)&nbsp;As&nbsp;String<br />
ReDim&nbsp;da(1023)&nbsp;As&nbsp;Byte<br />
Dim&nbsp;z&nbsp;As&nbsp;Long<br />
Dim&nbsp;zr&nbsp;As&nbsp;Long<br />
Dim&nbsp;Srge&nbsp;As&nbsp;Long<br />
Dim&nbsp;hpid&nbsp;As&nbsp;Long<br />
Dim&nbsp;Minf&nbsp;As&nbsp;MEMORY_BASIC_INFORMATION<br />
Dim&nbsp;Mbsize&nbsp;As&nbsp;Long<br />
Dim&nbsp;Dda(100)&nbsp;As&nbsp;Byte<br />
Dim&nbsp;Zfr&nbsp;As&nbsp;Long<br />
Dim&nbsp;Zed&nbsp;As&nbsp;Long<br />
Dim&nbsp;Siz&nbsp;As&nbsp;Integer<br />
Dim&nbsp;Csiz&nbsp;As&nbsp;Integer<br />
Dim&nbsp;Shsiz&nbsp;As&nbsp;Integer<br />
Dim&nbsp;Mlng&nbsp;As&nbsp;Long<br />
Mbsize&nbsp;=&nbsp;Len(Minf)<br />
Zfr&nbsp;=&nbsp;0<br />
Zed&nbsp;=&nbsp;CLng("&#038;H"&nbsp;&&nbsp;GetMemoryByPID(GamePid))<br />
LRsc&nbsp;=&nbsp;Rsc<br />
Rsc&nbsp;=&nbsp;-1<br />
Siz&nbsp;=&nbsp;2<br />
Shsiz&nbsp;=&nbsp;2<br />
mstr&nbsp;=&nbsp;Fz(ZJSZ)<br />
'循环看数组的长度，并转换成字节数组<br />
Dim&nbsp;i&nbsp;As&nbsp;Integer<br />
For&nbsp;i&nbsp;=&nbsp;Len(mstr)&nbsp;To&nbsp;2&nbsp;Step&nbsp;-2<br />
Dda((i&nbsp;/&nbsp;2)&nbsp;-&nbsp;1)&nbsp;=&nbsp;CInt("&#038;h"&nbsp;&&nbsp;Mid$(mstr,&nbsp;Len(mstr)&nbsp;-&nbsp;i&nbsp;+&nbsp;1,&nbsp;2))<br />
Next<br />
hpid&nbsp;=&nbsp;OpenProcess(&#038;H1F0FFF,&nbsp;False,&nbsp;CLng(Pid))<br />
z&nbsp;=&nbsp;Zfr&nbsp;'设置开始内存<br />
Do&nbsp;While&nbsp;z&nbsp;&lt;&nbsp;Zed&nbsp;-&nbsp;1&nbsp;'判断是否小于结束内存<br />
ret&nbsp;=&nbsp;VirtualQueryEx(hpid,&nbsp;z,&nbsp;Minf,&nbsp;Mbsize)&nbsp;'查询地址空间中内存地址的信息<br />
If&nbsp;ret&nbsp;=&nbsp;0&nbsp;Then<br />
Srge&nbsp;=&nbsp;1023<br />
zr&nbsp;=&nbsp;z<br />
Else<br />
Srge&nbsp;=&nbsp;Minf.RegionSize&nbsp;-&nbsp;1<br />
zr&nbsp;=&nbsp;Minf.BaseAddress<br />
If&nbsp;(Minf.Protect&nbsp;And&nbsp;4)&nbsp;And&nbsp;Minf.State&nbsp;=&nbsp;4096&nbsp;Then<br />
ReDim&nbsp;da(Srge)&nbsp;As&nbsp;Byte<br />
a&nbsp;=&nbsp;ReadProcessMemory(hpid,&nbsp;zr,&nbsp;da(0),&nbsp;Srge&nbsp;+&nbsp;1,&nbsp;ByVal&nbsp;0&#038;)<br />
If&nbsp;a&nbsp;&lt;&gt;&nbsp;0&nbsp;Then<br />
For&nbsp;zz&nbsp;=&nbsp;0&nbsp;To&nbsp;Srge&nbsp;Step&nbsp;Shsiz<br />
If&nbsp;Srge&nbsp;-&nbsp;zz&nbsp;&lt;&nbsp;Siz&nbsp;-&nbsp;1&nbsp;Then&nbsp;Exit&nbsp;For<br />
For&nbsp;bj&nbsp;=&nbsp;0&nbsp;To&nbsp;Siz&nbsp;-&nbsp;1<br />
If&nbsp;da(zz&nbsp;+&nbsp;bj)&nbsp;&lt;&gt;&nbsp;Dda(bj)&nbsp;Then&nbsp;Exit&nbsp;For<br />
Next&nbsp;bj<br />
If&nbsp;bj&nbsp;=&nbsp;Siz&nbsp;Then&nbsp;Rsc&nbsp;=&nbsp;Rsc&nbsp;+&nbsp;1:&nbsp;Rst(Rsc)&nbsp;=&nbsp;zr&nbsp;+&nbsp;zz<br />
Next&nbsp;zz<br />
End&nbsp;If<br />
End&nbsp;If<br />
End&nbsp;If<br />
z&nbsp;=&nbsp;zr&nbsp;+&nbsp;Srge&nbsp;+&nbsp;1<br />
DoEvents<br />
Loop<br />
CloseHandle&nbsp;(hpid)<br />
AobScan&nbsp;=&nbsp;Hex$(Rst(0))<br />
End&nbsp;Function</textarea><br/><br/><textarea class="code" rows="10" cols="50"><br />
Private&nbsp;Sub&nbsp;Command3_Click()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MsgBox&nbsp;AobScan(GamePid,&nbsp;"1d&nbsp;8e&nbsp;25&nbsp;00&nbsp;19")<br />
End&nbsp;Sub</textarea></p>
]]></content:encoded>
			<wfw:commentRss>http://yulv.net/archives/515/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>判断当前游戏是否为全屏状态</title>
		<link>http://yulv.net/archives/372</link>
		<comments>http://yulv.net/archives/372#comments</comments>
		<pubDate>Thu, 18 Jun 2009 14:02:49 +0000</pubDate>
		<dc:creator>JiaJia</dc:creator>
				<category><![CDATA[学习编程]]></category>
		<category><![CDATA[Ｃ／Ｃ＋＋]]></category>

		<guid isPermaLink="false">http://yulv.net/archives/372</guid>
		<description><![CDATA[方法一：<br/>　　最简单的方法，判断当前窗口大小是否跟屏幕分辨率相同，相同则为全屏状态。不过要注意桌面进程 Explorer 的处理<br/><br/>方法二：<br/>　　注册一个Appbar（桌面工具栏）是类似微软视窗系统的任务条的窗口。它紧靠屏幕边缘，典型的桌面工具栏包括快速访问其他应用程序和窗口的按钮。系统会防止其他应用程序使用被appbar占用的区域。在任何时刻桌面都可以同时共存多个appbar。
]]></description>
				<content:encoded><![CDATA[<p>方法一：<br/>　　最简单的方法，判断当前窗口大小是否跟屏幕分辨率相同，相同则为全屏状态。不过要注意桌面进程 Explorer 的处理<br/><br/>方法二：<br/>　　注册一个Appbar（桌面工具栏）是类似微软视窗系统的任务条的窗口。它紧靠屏幕边缘，典型的桌面工具栏包括快速访问其他应用程序和窗口的按钮。系统会防止其他应用程序使用被appbar占用的区域。在任何时刻桌面都可以同时共存多个appbar。<br/><br/>使用的API: SHAppBarMessage (原型如下:)<br/><br />
<blockquote>
<div class="quote">WINSHELLAPI UINT APIENTRY SHAppBarMessage( DWORD dwMessage, PAPPBARDATA pData);</div>
</blockquote>
<p><br/>　　这个API可以向系统发送一个appbar message（也就是dwMessage，有很多消息，可以查阅MSDN），然后系统通过pData返回你想知道的信息，这里我们主要用这个API来注册一个新的appbar。这里还需要关注的是APPBARDATA这个结构体。<br/><br/>检测全屏的具体实现代码如下：<br/><br />
<blockquote>
<div class="quote">APPBARDATA abd;<br/>memset(&#038;abd, 0, sizeof(abd));<br/>// Specify the structure size and handle to the appbar.<br/>abd.cbSize = sizeof(APPBARDATA);<br/>abd.hWnd = hwndAccessBar;<br/>abd.uCallbackMessage = MSG_APPBAR_MSGID;<br/>!::SHAppBarMessage(ABM_NEW, &#038;abd);</div>
</blockquote>
<p><br/>　　注意MSG_APPBAR_MSGID这个，这是你自己定义的消息ID，当有全屏创建或者取消的时候，会给句柄为hwndAccessBar的窗口发送消息ID为MSG_APPBAR_MSGID的消息，具体到全屏消息，此时WPARAM为ABN_FULLSCREENAPP，而LPARAM则能够判断当前是有窗口全屏了还是有窗口取消全屏了，(BOOL) lParam为TRUE表示有窗口全屏了，而(BOOL) lParam为FALSE则表示有窗口取消全屏状态了。代码如下：<br/><br />
<blockquote>
<div class="quote">LRESULT CWinHook::WindowProc(UINT msg, WPARAM wp, LPARAM lp)&nbsp;&nbsp; <br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;if (MSG_APPBAR_MSGID == msg)<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch((UINT)wp)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case ABN_FULLSCREENAPP:<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (TRUE == (BOOL)lp)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TRACE(TEXT("一个窗口全屏了\n"));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;KAppBarMsg::m_bFullScreen = TRUE;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TRACE(TEXT("一个窗口取消全屏了\n"));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;KAppBarMsg::m_bFullScreen = FALSE;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;return CSubclassWnd::WindowProc(msg, wp, lp);<br/>}</div>
</blockquote>
<p><br/>附注：后来发现vista下面没有XP下灵敏，不知道怎么回事，vista下偶尔会失败，很奇怪。<br/></p>
]]></content:encoded>
			<wfw:commentRss>http://yulv.net/archives/372/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>关于DEP(数据执行保护)的分析</title>
		<link>http://yulv.net/archives/370</link>
		<comments>http://yulv.net/archives/370#comments</comments>
		<pubDate>Sat, 13 Jun 2009 04:32:59 +0000</pubDate>
		<dc:creator>JiaJia</dc:creator>
				<category><![CDATA[学习编程]]></category>
		<category><![CDATA[DEP]]></category>

		<guid isPermaLink="false">http://yulv.net/archives/370</guid>
		<description><![CDATA[1.什么是DEP<br/>2.DEP能保护什么?<br/>3.可以绕过DEP吗？<br/>4.DEP在内核中到底是如何实现的?
]]></description>
				<content:encoded><![CDATA[<p><b>1.什么是DEP</b><br/>DEP,全称是Data Excution Protection,中名叫数据执行保护，是XP+sp2,Win2K03+sp1中加入的对内存的一种保护，用来防止恶意程序对系统的攻击，如溢出。<br/>现在只有两种设置方式：<br/>一、是只为系统关键进程和服务提供DEP保护，这也是默认选项。<br/>二、是为所有程序和服务提供DEP保护，除去用户手动指定的程序。<br/>其设置在"我的电脑"->右键菜单"属性"->"高级"->"性能 - 设置"->"数据执行保护"<br/><br/><b>2.DEP能保护什么?</b><br/>个人认为DEP就是专门为防止溢出设计的，当然这么说是有点狭隘了，毕竟这种机制完善了CPU的内存管理机制。感觉每一个指令执行之前都进行内存页属性的检测有点太费资源了。<br/>一句话，<font color="Blue">DEP可以使指定的内存页不具有可执行属性</font>。<br/>这样一来，如果指定栈所在的内存页不可执行，那么，当我们要栈上溢出时，我们的Shellcode将难以被执行。<br/>所以，DEP保护的就是内存，保护指定的内存上的代码不能被执行，这样就可以达到反溢出的目的。<br/>当然，这是微软的一厢情愿罢了。因为越过这个限制也并不是一件难事。<br/><br/><b>3.可以绕过DEP吗?如果可以,如何绕过呢?</b><br/>答案是肯定的，可以绕过。即使是硬件上的DEP保护也是可以的。<br/>有一个API,改变指定内存页的属性的，VirtualProtect(),当然，还有其它的API，如<br/>VirtualProtectEx(),ZwProtectVirtulMemory(),不过都是封闭在VirtualProtect()中。<br/>所以，我们溢出的时候，把返回地址设计为这个API的地址，再精心构造一个栈为调用这个API的栈，就可以<br/>改变当前栈的内存页的属性，使其从"不可执行"变成"可执行".<br/>这个过程的示例如下面的一段代码<br/><br />
<blockquote>
<div class="quote">_test proc<br/> ;push 04<br/> ;invoke VirtualProtect,esp,30h,<font color="Red">PAGE_EXECUTE_READWRITE</font>,esp<br/> ;pop eax<br/> mov dword ptr [esp+18h],4<br/> mov eax,esp<br/> add eax,18h<br/> mov dword ptr [esp+14h],eax;lpOldProtection<br/> mov dword ptr [esp+10h],40h;dwNewProtection<br/> mov dword ptr [esp+0ch],30h;dwRegionSize<br/> mov dword ptr [esp+8],esp;dwStartAddress<br/> mov dword ptr [esp],VirtualProtect;func addr<br/> mov eax,esp<br/> add eax,1ch<br/> mov dword ptr [esp+4],eax;return address from VirtualProtect<br/> mov dword ptr [esp+1ch],90909090h;our shellcode<br/> ret<br/>_test endp</div>
</blockquote>
<p><br/><b>4.DEP在内核中到底是如何实现的?</b><br/>这个问题我曾经费不了少时间去找答案，从内存操作的API上来看，<br/>有标准内存管理API，虚拟内存管理API，堆管理API，内存映射文件API<br/>从内存管理的结构上来看，有VAD，有PFN，有PTE，PDE，有段<br/>一开始我认为windows可能会在任何一个层面上做文章，可能是VAD，也可能是PFN，也可能是PTE<br/>并且我认为VAD的可能性比较大，因为PTE没有相关的bit位表示此页有没有可执行属性。PFN也没有。<br/>VAD倒是有相关的位表示页的可执行属性。<br/>经过一点点的测试和排除，发现VAD与此并没有关系，用VirtualProtect()改变页的属性时，此页对应<br/>的VAD的flag位竟然毫无变化。<br/>那么只剩下PFN和PTE了，发现这个API调用前后,PFN的restore pte这个字段有变化，PTE的低双字却<br/>没有一点变化，高双字我时候我没有关心，我一直认为高双字是用于寻址4G以外的物理内存地址的。<br/>然后我手动把PFN的restore pte改变成上面提到的API改成的值，但是结果却让人失望，我拷入shellcode<br/>的页还是不可执行。<br/>尽管这时，我还是没有意识到PTE的高双字发生的变化，并为此付出了代价，那就是二夜一天的对VirtualProtect()<br/>相关API的反汇编。<br/>VirtualProtect()调用了VirtualProtectEx()<br/>VirtualProtectEx()调用了ZwProtectVirtualMemory()<br/>ZwProtectVirtualMemory()通过sysenter进入内核,EAX中存放的服务号是0x89,对应的服务是NtProtecVirtualMemory()<br/>NtProtectVirtualMemory()又调用了MiProtectVirtualMemory()<br/>在MiProtectVirtualMemory()内部，计算出要改变其属性的内存页的PTE的地址，新的属性，然后调用<br/>MiFlushTbAndCapture()改变PTE的属性，但是我当时也只是看到把PTE的属性从067变成了027,和可执行属性还是<br/>没有关系，然后我再深入到MiFlushTbAndCapture()中，发现它主要又是调用KeFlushSingleTb()来改变指定PTE<br/>的属性的，深入到KeFlushSingleTb()内部，它主要是调用KeInterlockedSwapPte()来改变指定PTE的属性。<br/>而KeInterlockedSwapPte()的内部是比较简单的，来看看它的反汇编代码：<br/><br />
<blockquote>
<div class="quote">nt!KeInterlockedSwapPte:<br/>80541c08 53              push    ebx<br/>80541c09 56              push    esi<br/>80541c0a 8b5c2410        mov     ebx,dword ptr [esp+10h] ;ebx=新的PTE值所在变量的地址<br/>80541c0e 8b74240c        mov     esi,dword ptr [esp+0Ch] ;esi=PTE地址<br/>80541c12 8b4b04          mov     ecx,dword ptr [ebx+4]   ;ecx=新PTE值高双字<br/>80541c15 8b1b            mov     ebx,dword ptr [ebx]     ;ebx=新PTE值低双字<br/>80541c17 8b5604          mov     edx,dword ptr [esi+4]   ;edx=旧PTE值高双字<br/>80541c1a 8b06            mov     eax,dword ptr [esi]     ;eax=旧PTE值低双字<br/>80541c1c 0fc70e          cmpxchg8b qword ptr [esi]</div>
</blockquote>
<p><br/>看到关键点了吧，就是一个cmpxch8b指令，这个指令是干什么的呢？<br/>执行的操作：edx,eax与DST相比较<br/>如果 (edx,eax)=(dst)<br/>则 ZF=1,(dst)<-(ecx,ebx)<br/>否则 ZF=0,(edx,eax)<-dst<br/>很简单，如果新的PTE属性和旧的不等，把PTE属性设置为新的属性。如果相等，则实际上等于不进行操作。<br/>从这里我才发现，他把PTE的高双字设置为0了，以前的值是0x80000000.<br/>所以，DEP是通过PTE的高双字的最高bit即bit63来实现的，这个位置位了，表示此页不可执行。没有置位，<br/>表示此页可以执行。而win2k下面的页目录和页表项只有32个bit,所以不可能提供DEP的这个保护位，因此<br/>DEP只有在64bit的PTE上才能实现。而只有cr4的bit5即PAE启用的时候，PTE才为64bit。<br/>所以，可以这么说吧，intel的奔腾CPU是早就有PAE属性位的，可以支持64位的页表项，而windows系统<br/>只有win2k的某个版本，winxp和win2003的某个server pack版本的内核才支持64的页表项。<br/>不管怎样，PTE的第63位控制着页的可执行属性，我后来查了IA,在IA的修正说明中，才提到这一点,并<br/>把这个位叫做EXB,却对此位的作用一字为提。<br/>但是我们是不能在ring3下操作PTE的，所以，绕过DEP还是得用return-to-lib的经典方式返回到VirtualProtect()<br/>来改变当前栈的属性。</p>
]]></content:encoded>
			<wfw:commentRss>http://yulv.net/archives/370/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VB Shell 实现压缩和解压缩 (Zip 或 Rar)</title>
		<link>http://yulv.net/archives/366</link>
		<comments>http://yulv.net/archives/366#comments</comments>
		<pubDate>Mon, 08 Jun 2009 02:23:23 +0000</pubDate>
		<dc:creator>JiaJia</dc:creator>
				<category><![CDATA[学习编程]]></category>
		<category><![CDATA[VB]]></category>

		<guid isPermaLink="false">http://yulv.net/archives/366</guid>
		<description><![CDATA[Private Sub ZipOrRar()<br/>    '将C盘的test文件夹压缩为test.rar文件<br/>    Shell App.Path + "\WinRar.exe M C:\test.rar C:\test"<br/>End Sub
]]></description>
				<content:encoded><![CDATA[<p>Private Sub ZipOrRar()<br/>    '将C盘的test文件夹压缩为test.rar文件<br/>    Shell App.Path + "\WinRar.exe M C:\test.rar C:\test"<br/>End Sub<br/><br/>Private Sub UnZipOrRar()<br/>    '将test.rar解压缩在C盘下<br/>    Shell App.Path + "\WinRar.exe X C:\test.rar C:\"<br/>End Sub<br/></p>
]]></content:encoded>
			<wfw:commentRss>http://yulv.net/archives/366/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>简单判断系统是不是Vista</title>
		<link>http://yulv.net/archives/364</link>
		<comments>http://yulv.net/archives/364#comments</comments>
		<pubDate>Sat, 06 Jun 2009 15:47:31 +0000</pubDate>
		<dc:creator>JiaJia</dc:creator>
				<category><![CDATA[学习编程]]></category>
		<category><![CDATA[Ｃ／Ｃ＋＋]]></category>

		<guid isPermaLink="false">http://yulv.net/archives/364</guid>
		<description><![CDATA[BYTE bVersion = (BYTE)GetVersion();<br/>	if (bVersion >= 6)<br/>	{<br/>		printf("主版本号：%X  : 当前系统 >= Vista\n",bVersion);<br/>	}else{<br/>		printf("主版本号：%X  : 当前系统 < Vista\n",bVersion);<br/>	}
]]></description>
				<content:encoded><![CDATA[<p>BYTE bVersion = (BYTE)GetVersion();<br/>	if (bVersion >= 6)<br/>	{<br/>		printf("主版本号：%X  : 当前系统 >= Vista\n",bVersion);<br/>	}else{<br/>		printf("主版本号：%X  : 当前系统 < Vista\n",bVersion);<br/>	}</p>
]]></content:encoded>
			<wfw:commentRss>http://yulv.net/archives/364/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>子类化 - zAddressOf</title>
		<link>http://yulv.net/archives/360</link>
		<comments>http://yulv.net/archives/360#comments</comments>
		<pubDate>Sat, 30 May 2009 06:53:09 +0000</pubDate>
		<dc:creator>JiaJia</dc:creator>
				<category><![CDATA[学习编程]]></category>
		<category><![CDATA[VB]]></category>
		<category><![CDATA[WarKey]]></category>
		<category><![CDATA[魔兽改键伴侣]]></category>
		<category><![CDATA[魔兽辅助]]></category>

		<guid isPermaLink="false">http://yulv.net/archives/360</guid>
		<description><![CDATA[zAddressOf 获取任意窗体、类、用户控件的指定函数的地址，代替VB自带的AddressOf函数。
]]></description>
				<content:encoded><![CDATA[<blockquote><div class="quote"><font color="#008000">'Return the address of the specified ordinal method on the oCallback object, 1 = last private method, 2 = second last private method, etc<br/></font><font color="#0000FF">Private Function </font><font color="#000000">zAddressOf(</font><font color="#0000FF">ByVal </font><font color="#000000">oCallback </font><font color="#0000FF">As Object</font><font color="#000000">, </font><font color="#0000FF">ByVal </font><font color="#000000">nOrdinal </font><font color="#0000FF">As Long</font><font color="#000000">) </font><font color="#0000FF">As Long<br/>    </font><font color="#008000">' Note: used both in subclassing and hooking routines<br/>  </font><font color="#0000FF">Dim </font><font color="#000000">bSub  </font><font color="#0000FF">As Byte                                                         </font><font color="#008000">'Value we expect to find pointed at by a vTable method entry<br/>  </font><font color="#0000FF">Dim </font><font color="#000000">bVal  </font><font color="#0000FF">As Byte<br/>  Dim </font><font color="#000000">nAddr </font><font color="#0000FF">As Long                                                         </font><font color="#008000">'Address of the vTable<br/>  </font><font color="#0000FF">Dim </font><font color="#000000">i     </font><font color="#0000FF">As Long                                                         </font><font color="#008000">'Loop index<br/>  </font><font color="#0000FF">Dim </font><font color="#000000">J     </font><font color="#0000FF">As Long                                                         </font><font color="#008000">'Loop limit<br/>  <br/>  </font><font color="#000000">RtlMoveMemory VarPtr(nAddr), ObjPtr(oCallback), </font><font color="#800080">4                         </font><font color="#008000">'Get the address of the callback object's instance<br/>  </font><font color="#0000FF">If Not </font><font color="#000000">zProbe(nAddr + </font><font color="#800080">&#038;H1C</font><font color="#000000">, i, bSub) </font><font color="#0000FF">Then                                 </font><font color="#008000">'Probe for a Class method<br/>    </font><font color="#0000FF">If Not </font><font color="#000000">zProbe(nAddr + </font><font color="#800080">&#038;H6F8</font><font color="#000000">, i, bSub) </font><font color="#0000FF">Then                              </font><font color="#008000">'Probe for a Form method<br/>      ' \\LaVolpe - Added propertypage offset<br/>      </font><font color="#0000FF">If Not </font><font color="#000000">zProbe(nAddr + </font><font color="#800080">&#038;H710</font><font color="#000000">, i, bSub) </font><font color="#0000FF">Then                            </font><font color="#008000">'Probe for a PropertyPage method<br/>        </font><font color="#0000FF">If Not </font><font color="#000000">zProbe(nAddr + </font><font color="#800080">&#038;H7A4</font><font color="#000000">, i, bSub) </font><font color="#0000FF">Then                          </font><font color="#008000">'Probe for a UserControl method<br/>            </font><font color="#0000FF">Exit Function                                                   </font><font color="#008000">'Bail...<br/>        </font><font color="#0000FF">End If<br/>      End If<br/>    End If<br/>  End If<br/>  <br/>  </font><font color="#000000">i = i + </font><font color="#800080">4                                                                 </font><font color="#008000">'Bump to the next entry<br/>  </font><font color="#000000">J = i + </font><font color="#800080">1024                                                              </font><font color="#008000">'Set a reasonable limit, scan 256 vTable entries<br/>  </font><font color="#0000FF">Do While </font><font color="#000000">i < J<br/>    RtlMoveMemory VarPtr(nAddr), i, </font><font color="#800080">4                                       </font><font color="#008000">'Get the address stored in this vTable entry<br/>    <br/>    </font><font color="#0000FF">If </font><font color="#000000">IsBadCodePtr(nAddr) </font><font color="#0000FF">Then                                             </font><font color="#008000">'Is the entry an invalid code address?<br/>      </font><font color="#000000">RtlMoveMemory VarPtr(zAddressOf), i - (nOrdinal * </font><font color="#800080">4</font><font color="#000000">), </font><font color="#800080">4               </font><font color="#008000">'Return the specified vTable entry address<br/>      </font><font color="#0000FF">Exit Do                                                               </font><font color="#008000">'Bad method signature, quit loop<br/>    </font><font color="#0000FF">End If<br/>    </font><font color="#000000">RtlMoveMemory VarPtr(bVal), nAddr, </font><font color="#800080">1                                    </font><font color="#008000">'Get the byte pointed to by the vTable entry<br/>    </font><font color="#0000FF">If </font><font color="#000000">bVal <> bSub </font><font color="#0000FF">Then                                                    </font><font color="#008000">'If the byte doesn't match the expected value...<br/>      </font><font color="#000000">RtlMoveMemory VarPtr(zAddressOf), i - (nOrdinal * </font><font color="#800080">4</font><font color="#000000">), </font><font color="#800080">4               </font><font color="#008000">'Return the specified vTable entry address<br/>      </font><font color="#0000FF">Exit Do                                                               </font><font color="#008000">'Bad method signature, quit loop<br/>    </font><font color="#0000FF">End If<br/>    <br/>    </font><font color="#000000">i = i + </font><font color="#800080">4                                                               </font><font color="#008000">'Next vTable entry<br/>  </font><font color="#0000FF">Loop<br/>End Function<br/><br/></font><font color="#008000">'Probe at the specified start address for a method signature<br/></font><font color="#0000FF">Private Function </font><font color="#000000">zProbe(</font><font color="#0000FF">ByVal </font><font color="#000000">nStart </font><font color="#0000FF">As Long</font><font color="#000000">, </font><font color="#0000FF">ByRef </font><font color="#000000">nMethod </font><font color="#0000FF">As Long</font><font color="#000000">, </font><font color="#0000FF">ByRef </font><font color="#000000">bSub </font><font color="#0000FF">As Byte</font><font color="#000000">) </font><font color="#0000FF">As Boolean<br/>  Dim </font><font color="#000000">bVal    </font><font color="#0000FF">As Byte<br/>  Dim </font><font color="#000000">nAddr   </font><font color="#0000FF">As Long<br/>  Dim </font><font color="#000000">nLimit  </font><font color="#0000FF">As Long<br/>  Dim </font><font color="#000000">nEntry  </font><font color="#0000FF">As Long<br/>  <br/>  </font><font color="#000000">nAddr = nStart                                                            </font><font color="#008000">'Start address<br/>  </font><font color="#000000">nLimit = nAddr + </font><font color="#800080">32                                                       </font><font color="#008000">'Probe eight entries<br/>  </font><font color="#0000FF">Do While </font><font color="#000000">nAddr < nLimit                                                   </font><font color="#008000">'While we've not reached our probe depth<br/>    </font><font color="#000000">RtlMoveMemory VarPtr(nEntry), nAddr, </font><font color="#800080">4                                  </font><font color="#008000">'Get the vTable entry<br/>    <br/>    </font><font color="#0000FF">If </font><font color="#000000">nEntry <> </font><font color="#800080">0 </font><font color="#0000FF">Then                                                     </font><font color="#008000">'If not an implemented interface<br/>      </font><font color="#000000">RtlMoveMemory VarPtr(bVal), nEntry, </font><font color="#800080">1                                 </font><font color="#008000">'Get the value pointed at by the vTable entry<br/>      </font><font color="#0000FF">If </font><font color="#000000">bVal = </font<br />
><font color="#800080">&#038;H33 </font><font color="#0000FF">Or </font><font color="#000000">bVal = </font><font color="#800080">&#038;HE9 </font><font color="#0000FF">Then                                    </font><font color="#008000">'Check for a native or pcode method signature<br/>        </font><font color="#000000">nMethod = nAddr                                                     </font><font color="#008000">'Store the vTable entry<br/>        </font><font color="#000000">bSub = bVal                                                         </font><font color="#008000">'Store the found method signature<br/>        </font><font color="#000000">zProbe = </font><font color="#0000FF">True                                                       </font><font color="#008000">'Indicate success<br/>        </font><font color="#0000FF">Exit Do                                                             </font><font color="#008000">'Return<br/>      </font><font color="#0000FF">End If<br/>    End If<br/>    <br/>    </font><font color="#000000">nAddr = nAddr + </font><font color="#800080">4                                                       </font><font color="#008000">'Next vTable entry<br/>  </font><font color="#0000FF">Loop<br/>End Function </font></div>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://yulv.net/archives/360/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NtSuspendProcess(挂起进程)/NtResumeProcess(恢复进程)</title>
		<link>http://yulv.net/archives/359</link>
		<comments>http://yulv.net/archives/359#comments</comments>
		<pubDate>Sat, 30 May 2009 05:56:29 +0000</pubDate>
		<dc:creator>JiaJia</dc:creator>
				<category><![CDATA[学习编程]]></category>
		<category><![CDATA[Bon Jovi]]></category>
		<category><![CDATA[VB]]></category>

		<guid isPermaLink="false">http://yulv.net/archives/359</guid>
		<description><![CDATA[NtSuspendProcess/NtResumeProcess API 使用示例
]]></description>
				<content:encoded><![CDATA[<blockquote><div class="quote"><font color="#0000FF">Private Declare Function </font><font color="#000000">OpenProcess </font><font color="#0000FF">Lib </font><font color="#808080">"kernel32" </font><font color="#000000">(</font><font color="#0000FF">ByVal </font><font color="#000000">dwDesiredAccess </font><font color="#0000FF">As Long</font><font color="#000000">, </font><font color="#0000FF">ByVal </font><font color="#000000">bInheritHandle </font><font color="#0000FF">As Long</font><font color="#000000">, </font><font color="#0000FF">ByVal </font><font color="#000000">dwProcessId </font><font color="#0000FF">As Long</font><font color="#000000">) </font><font color="#0000FF">As Long<br/>Private Declare Function </font><font color="#000000">CloseHandle </font><font color="#0000FF">Lib </font><font color="#808080">"kernel32" </font><font color="#000000">(</font><font color="#0000FF">ByVal </font><font color="#000000">hObject </font><font color="#0000FF">As Long</font><font color="#000000">) </font><font color="#0000FF">As Long<br/>Private Const </font><font color="#000000">SYNCHRONIZE = </font><font color="#800080">&#038;H100000<br/></font><font color="#0000FF">Private Const </font><font color="#000000">STANDARD_RIGHTS_REQUIRED = </font><font color="#800080">&#038;HF0000<br/></font><font color="#0000FF">Private Const </font><font color="#000000">PROCESS_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED </font><font color="#0000FF">Or </font><font color="#000000">SYNCHRONIZE </font><font color="#0000FF">Or </font><font color="#800080">&#038;HFFF</font><font color="#000000">)<br/></font><font color="#0000FF">Private Declare Function </font><font color="#000000">NtSuspendProcess </font><font color="#0000FF">Lib </font><font color="#808080">"ntdll.dll" </font><font color="#000000">(</font><font color="#0000FF">ByVal </font><font color="#000000">hProc </font><font color="#0000FF">As Long</font><font color="#000000">) </font><font color="#0000FF">As Long<br/>Private Declare Function </font><font color="#000000">NtResumeProcess </font><font color="#0000FF">Lib </font><font color="#808080">"ntdll.dll" </font><font color="#000000">(</font><font color="#0000FF">ByVal </font><font color="#000000">hProc </font><font color="#0000FF">As Long</font><font color="#000000">) </font><font color="#0000FF">As Long<br/>Private Declare Function </font><font color="#000000">TerminateProcess </font><font color="#0000FF">Lib </font><font color="#808080">"kernel32" </font><font color="#000000">(</font><font color="#0000FF">ByVal </font><font color="#000000">hProcess </font><font color="#0000FF">As Long</font><font color="#000000">, </font><font color="#0000FF">ByVal </font><font color="#000000">uExitCode </font><font color="#0000FF">As Long</font><font color="#000000">) </font><font color="#0000FF">As Long<br/>Private </font><font color="#000000">hProcess </font><font color="#0000FF">As Long<br/><br/>Private Sub </font><font color="#000000">cmdSuspend_Click()<br/>    </font><font color="#0000FF">If </font><font color="#000000">IsNumeric(txtPid.Text) </font><font color="#0000FF">Then<br/>        </font><font color="#000000">hProcess = OpenProcess(PROCESS_ALL_ACCESS, </font><font color="#0000FF">False</font><font color="#000000">, </font><font color="#0000FF">CLng</font><font color="#000000">(txtPid.Text))<br/>        </font><font color="#0000FF">If </font><font color="#000000">hProcess <> </font><font color="#800080">0 </font><font color="#0000FF">Then </font><font color="#000000">NtSuspendProcess hProcess<br/>    </font><font color="#0000FF">End If<br/>    </font><font color="#000000">CloseHandle hProcess<br/></font><font color="#0000FF">End Sub<br/><br/>Private Sub </font><font color="#000000">cmdResume_Click()<br/>    </font><font color="#0000FF">If </font><font color="#000000">IsNumeric(txtPid.Text) </font><font color="#0000FF">Then<br/>        </font><font color="#000000">hProcess = OpenProcess(PROCESS_ALL_ACCESS, </font><font color="#0000FF">False</font><font color="#000000">, </font><font color="#0000FF">CLng</font><font color="#000000">(txtPid.Text))<br/>        </font><font color="#0000FF">If </font><font color="#000000">hProcess <> </font><font color="#800080">0 </font><font color="#0000FF">Then </font><font color="#000000">NtResumeProcess hProcess<br/>    </font><font color="#0000FF">End If<br/>    </font><font color="#000000">CloseHandle hProcess<br/></font><font color="#0000FF">End Sub<br/><br/>Private Sub </font><font color="#000000">cmdTerminate_Click()<br/>    </font><font color="#0000FF">If </font><font color="#000000">IsNumeric(txtPid.Text) </font><font color="#0000FF">Then<br/>        </font><font color="#000000">hProcess = OpenProcess(PROCESS_ALL_ACCESS, </font><font color="#0000FF">False</font><font color="#000000">, </font><font color="#0000FF">CLng</font><font color="#000000">(txtPid.Text))<br/>        </font><font color="#0000FF">If </font><font color="#000000">hProcess <> </font><font color="#800080">0 </font><font color="#0000FF">Then </font><font color="#000000">TerminateProcess hProcess, </font><font color="#800080">0<br/>    </font><font color="#0000FF">End If<br/>End Sub</font></div>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://yulv.net/archives/359/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
