4.2.2 XX游戏驱动保护代码书写-50课
A、恢复NtOpenThread
B、恢复NtOpenProcess函数
C、恢复NtReadVirtualMemory 让CE可读
D、恢复NtWriteVirtualMemory让CE可写
E、Ret指令详解
F、Hook代码编写并测试
G、过非法保护测试
课时:44+4
OpenProcess //NtOpenProcess+0x21E //SSDT 122
OpenThread //NtOpenThread+0x214 //SSDT 128
ReadProcessMemory //NtReadVirtualMemory+0 //SSDT 186
WriteProcessMemory //NtWriteVirtualMemory+0 //SSDT 277
Ret指令详解
ret相当于 jmp dword ptr[esp];add esp,4;//但并不等价哟
一、用 MmGetSystemRoutineAddress 取得
NtOpenProcess和NtOpenThread的地址存放到
PNtOpenProcess和PNtOpenThread中;
二、通过特征码定位下边4个地址以增加兼容性
DWORD NtOpenProcess_21E=0x805cc61a; //jmp myNtOpenProcess
DWORD NtOpenThread_214=805cc89ch; //jmp myNtOpenThread
DWORD NtOpenThread_214_B=805cc8a7h; //Call ret Addr
DWORD NtOpenProcess_21E_B=805cc625h;//Call ret Addr
三、写HOOK代码
===================================================
笔记:杂音好大啊!
A部分:将上节课代码复制过来修改一下,
//nt!NtReadVirtualMemory:
//805b528a 6a1c push 1Ch
//805b528c 68e8ae4d80 push offset nt!MmClaimParameterAdjustDownTime+0x90 (804daee8)
DWORD Real_NtReadVirtualMemory_7 =0x805b5291;
DWORD Real_NtWriteVirtualMemory_7=0x805b5394;
DWORD NtOpenProcess_21E=0x805cc61a; //myNtOpenProcess
DWORD NtOpenThread_214=0x805cc89c; //myNtOpenThread
DWORD NtOpenThread_214_B=0x805cc8a7;
DWORD NtOpenProcess_21E_B=0x805cc625;
PVOID PObOpenObjectByPointer,PNtOpenProcess,PNtOpenThread;
DWORD ssdtaddr;
#pragma PAGECODE
__declspec(naked)VOID My_NtReadVirtualMemory()
{
//恢复前2条指令
__asm
{
push 1Ch
push 804daee8h
jmp Real_NtReadVirtualMemory_7
}
}
#pragma PAGECODE
__declspec(naked)VOID My_NtWriteVirtualMemory()
{
//恢复前2条指令
// nt!NtWriteVirtualMemory:
// 805b5394 6a1c push 1Ch
// 805b5396 6800af4d80 push offset nt!MmClaimParameterAdjustDownTime+0xa8 (804daf00)
__asm
{
push 1Ch
push 804daf00h
jmp Real_NtWriteVirtualMemory_7
}
}
// OpenProcess //NtOpenProcess+0x21E //SSDT 122
// nt!NtOpenProcess+0x21e:
// 805cc61a ff75c8 push dword ptr [ebp-38h] //jmp My_NtOpenPrcoess
// 805cc61d ff75dc push dword ptr [ebp-24h]
// 805cc620 e84706ffff call nt!ObOpenObjectByPointer (805bcc6c)
// 805cc625 8bf8 mov edi,eax
#pragma PAGECODE
__declspec(naked)VOID My_NtOpenPrcoess()
{
//恢复前2条指令
// nt!NtWriteVirtualMemory:
// 805b5394 6a1c push 1Ch
// 805b5396 6800af4d80 push offset
nt!MmClaimParameterAdjustDownTime+0xa8 (804daf00)
__asm
{
push dword ptr [ebp-38h]
push dword ptr [ebp-24h]
push NtOpenProcess_21E_B //DWORD NtOpenProcess_21E_B=805cc625h
jmp DWORD ptr [ PObOpenObjectByPointer] //(805bcc6c) ret c3 eip
ret
//jmp NtOpenProcess_21E_B
}
}
// OpenThread //NtOpenThread+0x214 //SSDT 128
// 805cc89c ff75cc push dword ptr [ebp-34h] //jmp DWORD NtOpenThread_214=805cc89ch;
// 805cc89f ff75e0 push dword ptr [ebp-20h]
// 805cc8a2 e8c503ffff call nt!ObOpenObjectByPointer (805bcc6c)
// 805cc8a7 8bf8 mov edi,eax
#pragma PAGECODE
__declspec(naked)VOID My_NtOpenThread()
{
//恢复前2条指令
// nt!NtWriteVirtualMemory:
// 805b5394 6a1c push 1Ch
// 805b5396 6800af4d80 push offset nt!MmClaimParameterAdjustDownTime+0xa8 (804daf00)
__asm
{
push dword ptr [ebp-34h]
push dword ptr [ebp-20h]
push NtOpenThread_214_B // DWORD NtOpenProcess_214_B=805cc8a7h
jmp PObOpenObjectByPointer /*(805bcc6c)*/
//jmp NtOpenProcess_214_B
}
}
#pragma PAGECODE
VOID HOOK()
{
UNICODE_STRING Us_ObOpenObjectByPointer, Us_NtOpenProcess, Us_NtOpenThread;//建立变量
RtlInitUnicodeString(&Us_ObOpenObjectByPointer,L"ObOpenObjectByPointer");//初始化RtlInitUnicodeString(&Us_NtOpenProcess,L"NtOpenProcess");//初始化
RtlInitUnicodeString(&Us_NtOpenThread,L"NtOpenThread");//初始化PObOpenObjectByPointer=MmGetSystemRoutineAddress(&Us_ObOpenObjectByPointer); PNtOpenProcess=MmGetSystemRoutineAddress(&Us_NtOpenProcess);//获得OP函数地址PNtOpenThread=MmGetSystemRoutineAddress(&Us_NtOpenThread); //获得OT函数地址__asm
{
Cli //内存保护
mov eax,cr0
and eax,not 10000h
mov cr0,eax
_asm int 3
// NtOpenProcess 还原
mov ebx,NtOpenProcess_21E
mov al,0xe9
mov byte ptr [ebx+0],al
lea eax,My_NtOpenPrcoess
sub eax,NtOpenProcess_21E
sub eax,5
mov [ebx+1],eax
// NtOpenThread 还原
mov ebx,NtOpenThread_214
mov byte ptr [ebx+0],0xe9
lea eax,My_NtOpenThread //通过公式计算
sub eax,NtOpenThread_214
sub eax,5
mov [ebx+1],eax
//ReadProcessMemory //NtReadVirtualMemory+0 //SSDT 186
//WriteProcessMemory //NtWriteVirtualMemory+0 //SSDT 277
mov eax, KeServiceDescriptorTable
mov eax,[eax] //address of KeServiceDescriptorTable
mov ssdtaddr,eax
mov eax,ssdtaddr
add eax,2e8h //0xBA * 4 ntreadvirtualmemoryaddr ssdt186 lea ebx, My_NtReadVirtualMemory //建立自己地址写入
mov ecx,[eax]
add ecx,7
mov Real_NtReadVirtualMemory_7,ecx//要跳回的地址
mov [eax],ebx //HOOK成我们自己的SSDT 186 hook My_NtReadVirtualMemory mov eax,ssdtaddr
add eax,454h //0x115*4 ntwritevirtualmemoryaddr ssdt227 lea ebx,My_NtWriteVirtualMemory
mov ecx,[eax]
add ecx,7
mov Real_NtWriteVirtualMemory_7,ecx//要跳回的地址
mov [eax],ebx
//去掉内存保护
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
}
写好代码后先虚拟机测试了一下没有成功,再次修改.这次好像正确了,用ME打开游戏扫描一下结果被检测到非法,那么将ME的SYS去掉再扫描一下.还是非法.
B部分:老师将passtp.h加进去修改好错误后进行编译,然后在本机里进行测试,在加载了驱动之后用另一款ME就可以搜索到数据了,但是用CE还是非法,因为游戏本身有针对CE的检测.
随记: 终于过了!老师功夫果然厉害!另外老师写代码也经常出错,我想我写代码出错就更多了,以后还是要一点一点的写,然后一点一点的测试,确保代码不出错的情况下再继续编写,否则出错真是闹心.
纯C语言写的一个小型游戏-源代码
/* A simple game*/ /*CopyRight: Guanlin*/ #include
C程序设计 扫雷游戏 一、设计题目:扫雷游戏 二、设计目的 1.使学生更深入地理解和掌握该课程中的有关基本概念,程序设计思想和方法。 2.培养学生综合运用所学知识独立完成课题的能力。 3.培养学生勇于探索、严谨推理、实事求是、有错必改,用实践来检验理论,全方位考虑问题等科学技术人员应具有的素质。 4.提高学生对工作认真负责、一丝不苟,对同学团结友爱,协作攻关的基
本素质。 5.培养学生从资料文献、科学实验中获得知识的能力,提高学生从别人经验中找到解决问题的新途径的悟性,初步培养工程意识和创新能力。 6.对学生掌握知识的深度、运用理论去处理问题的能力、实验能力、课程设计能力、书面及口头表达能力进行考核。 三、设计要求 1.汪洋和孔维亮组成设计小组。小组成员分工协作完成。要求每个成员有自己相对独立的模块,同时要了解其他组员完成的内容。 2.查阅相关资料,自学具体课题中涉及到的新知识。 3.采用结构化、模块化程序设计方法,功能要完善,界面要美观。 4.按要求写出课程设计报告,并于设计结束后1周内提交。 一概述 1)掌握数组指针的概念及其应用 2)培养团结合作精神 2. 课程设计的要求 要求我们有扎实的C语言知识,以及良好的编程习惯,能够熟练的应用循环,有毅力,还要求我们有较强的合作精神,善于总结。同时还要求我们自学C语言作图部分知识。在必要时还要上网查相关资料。 3.课程设计的主要设计思想 扫雷游戏主要用了一个10行10列的二维数组,刚开始利用random随机布雷。 每一个程序最主要的是算法。扫雷游戏算法的重点是一开始统计好每个格子周围有多少雷,当鼠标左键点在格子上时做出判断,如果周围8个格子有雷则显示出雷数,如果没有雷则显示空白格(在四个角的格子显示周围3个格子,其它边缘的格子显示周围5个的状态),我们在主函数中用两个for语句来判断周围雷数。我们还加了鼠标处理函数。 如果格子上有雷则调用函FailExitGame(),显示“Fail!”,游戏结束。若所有的雷都标出,且所有的格子都处理过,则调用函数ExitGame(),显示“OK,Good!”,游戏结束。游戏结束后,按任意键出去。
C语言游戏源代码 1、简单的开机密码程序 #include "conio.h" #include "string.h" #include "stdio.h" void error() {window(12,10,68,10); textbackground(15); textcolor(132); clrscr(); cprintf("file or system error! you can't enter the system!!!"); while(1); /*若有错误不能通过程序*/ } void look() {FILE *fauto,*fbak; char *pass="c:\\windows\\password.exe"; /*本程序的位置*/ char a[25],ch; char *au="autoexec.bat",*bname="hecfback.^^^"; /*bname 是autoexec.bat 的备份*/ setdisk(2); /*set currently disk c:*/ chdir("\\"); /*set currently directory \*/ fauto=fopen(au,"r+"); if (fauto==NULL) {fauto=fopen(au,"w+"); if (fauto==NULL) error();} fread(a,23,1,fauto); /*读取autoexec.bat前23各字符*/ a[23]='\0'; if (strcmp(a,pass)==0) /*若读取的和pass指针一样就关闭文件,不然就添加*/ fclose(fauto); else {fbak=fopen(bname,"w+"); if (fbak==NULL) error(); fwrite(pass,23,1,fbak); fputc('\n',fbak); rewind(fauto); while(!feof(fauto)) {ch=fgetc(fauto); fputc(ch,fbak);} rewind(fauto); rewind(fbak); while(!feof(fbak))
import javax.swing.ImageIcon; public class Block { String name; //名字,比如"雷"或数字int aroundMineNumber; //周围雷的数目 ImageIcon mineIcon; //雷的图标 boolean isMine=false; //是否是雷 boolean isMark=false; //是否被标记 boolean isOpen=false; //是否被挖开 public void setName(String name) { https://www.wendangku.net/doc/019474435.html,=name; } public void setAroundMineNumber(int n) { aroundMineNumber=n; } public int getAroundMineNumber() { return aroundMineNumber; } public String getName() { return name; } public boolean isMine() { return isMine; } public void setIsMine(boolean b) { isMine=b; } public void setMineIcon(ImageIcon icon){ mineIcon=icon; } public ImageIcon getMineicon(){ return mineIcon; }
public boolean getIsOpen() { return isOpen; } public void setIsOpen(boolean p) { isOpen=p; } public boolean getIsMark() { return isMark; } public void setIsMark(boolean m) { isMark=m; } } import java.util.*; import javax.swing.*; public class LayMines{ ImageIcon mineIcon; LayMines() { mineIcon=new ImageIcon("mine.gif"); } public void layMinesForBlock(Block block[][],int mineCount){ int row=block.length; int column=block[0].length; LinkedList
猜数字游戏的VB代码 本猜数字游戏的方法及规则: 系统自动生成一个四位数(四个数字没有重复),玩者需要猜中这个数字。玩者在四个文本框内输入四个数字,按“ENTER”后,如果猜对,则文本框变绿,本轮结束,按“CLEAR”进入下一轮。如果不对,则会在下面显示“xAxB”,其中“xA”表示有四个数字中有多少个数字是数字和所在位置都猜对的,“xB”表示有多少个数字猜对但是所在位置不对。比如,答案是“1234”,玩者猜“5432”,则显示“1A2B”,因为“3”猜对且位置也对,“4”猜对但位置不对,“2”猜对但位置不对。如果玩者猜“1324”,则显示“2A2B”;如果玩者猜“4567”,则显示“0A1B”;如果玩者猜“4256”,则显示“1A1B”,原因自己推。(四位数也可能是零开头。)最多猜错十次,如十次没有猜对,则游戏失败,本轮结束,按“CLEAR”进入下一轮。按“QUIT”可查看答案,同时本轮结束。各控件在界面上的布局如下:
Option Explicit Private Sub Command1_Click() '此为“确认”按钮。 If Form1.ForeColor <> vbMagenta Then If Command2.Enabled = False Then Dim keydig(1 To 4) As Integer, ansdig(1 To 4) As Integer Dim n, m, cnt_A, cnt_B As Integer, isappliable As Boolean Static count, keynum As Integer 'command按钮事件执行终,必须使变量count仍然残留。 Do If count = 0 Then '“count”变量计算Command1_Click执行的次数,每执行一次增加1。 Randomize keynum = Int(Rnd * (9876 - 123 + 1)) + 123 '生成一个四位随机整数。 End If '3rd
颜色代码
巧用Dreamweaver轻松制作网页页内连接 在网页制作中我们经常会遇到有时需要制作页内连接的情况,比如首先列出一个目录,然后后面内容是按目录列出的,我们需要实现的是当点击目录中的一项时,直接转到内容页面。 首先把光标定位到要连接的内容页面的位置的左侧,然后插入命名锚记。 给锚记命名一个名称。 然后再选择目录,设置超级连接。
保存后,按F12浏览。 Dreamweaver8轻松实现文本的段落缩进 我们在用Drwamweaver书写英文文本时,段落一般不缩进(不支持半角空格);但我们大多的时候都是用中文书写格式,必须在每段开头空两个汉字的位置。但浏览器对于文本中的空格,不管多少只认一个空格。如何在Drwamweaver 中实现文本的段落缩进,也就成了网页制作中的一大难题。针对这一问题,本文为大家提供以下几种解决办法。 一、用自Dreaweave身所带的功能 1、在Dreamweaver中执行下面操作4次就可以插入两个汉字大小的空格。 2、用同背景色相同颜色的字符来完成插入空格,这种方法操作比较繁琐、不易修改,而且在浏览内容被选取时,隐藏的字符就曝光了。 二、用HTML语言 用HTML语言方实现中文段落缩进。对于不懂HTML的初学者来说就有些困难了。 1、预格式(PRE) 用预格式编写的源文件,在显示时照源文件中的排版字样显示,空行和空格都能很清楚地区别开来。如源文件为:〈pre〉
--预格式显示…… 〈/pre〉 网页就会按照你预先设置好的显示方式显示,即在“预格式显示”的前面就会空两个汉字的位置。 2、插入特殊的空格字符“ ” “ ”代表非显示空格字符。插入若干个“ ”字符,中间用分号(;)或者空格隔开,也可以实现中文段落缩进。不过在Netscape 3.01中只能写小写字母,而在IE中大小写都可以。(此方法易产生乱码,不建议采用) 三、用输入法的全角 如果你用的是智能ABC的拼音输入的话,那请按SHIFT+空格,这时输入法的属性栏上的半月形就变成了圆形了,然后再敲空格键,空格就出来了。另外智能陈桥五笔的全角方式也可以直接输入空格。这种方法相对比较简单,缺点是英文字符集下,全角空格会变成乱码。 四、另类方法 1、插入点图或图形: 点图是指图片中只有一个或几个像素点,用肉眼看不出来。当我们在段落开头插入这样一个点图,并用HSPACE和VSPACE属性来调整点图的左右和上下的空格,以达到段落缩进。 2、插入没有边框和内容的表格: 这种方式与上述的插入图形方式类似,该表格没有边框和内容而是空表格。用TABLE的WIDTH和HEIGHT属性调整表格大小适合缩进的需要。利用表格来定位一般来说比较可靠,这种方法容易使页面的源文件变大。因此也不见得是格式控制的首选。 最后告诉你一个最原始的办法:在一些文字编辑软件中(比如记事本)复制空格,然后在Dreamweaver中进行粘贴。 五、CSS方法 把标记加上一些属性就可以实现,
就可以了!本站推荐使用此方法,以后网页教学网也要改版符合WEB标准的网站的。介绍了这么多种,用哪种好呢?各位可以按自己的喜好而定。WindowsXP家用版操作系统也能安装IIS 事前准备 1、Windows XP HomeEdit 中文版CD(拷在硬盘也可以) 2、默认你的XP是安装在C:\WINDOWS下 开始动手 (如果你怕改错,先把C:\WINDOWS\INF\SYSOC.INF做一份备份) 用记事本打开C:\WINDOWS\INF\SYSOC.INF,在[COMPONENTS]下找到一行: iis=iis.dll,OcEntry,iis.inf,hide,7 然后把它改成 iis=iis2.dll,OcEntry,iis2.inf,,7 保存。 怎样编写CSS? 从上面的例子中,我们可以看到CSS的语句是内嵌在HTML文档内的。所以,编写CSS的方法和编写HTML文档的方法是一样的。 您可以用任何一种文本编辑工具来编写。比如Windows下的记事本和写字板、专门的HTML文本编辑工具(Frontpage、Ultraedit等),都可以用来编辑CSS文档。 那么您可能会问,独立编辑好的CSS文档怎样加入到HTML文档中呢?其实在第一章中的例子里已经介绍了两种方法。 一种是把CSS文档放到
文档中: 其中