Ring0 Call Ring3

pjf(jfpan20000@sina.com)
很久没写什么东西,一来文笔太烂,二来我不是一般的懒。这个东西一看题目也就知道又是一篇无聊的帖子,凑凑数先。
因为最近决定把读本科时的古董机上的东西收拾一下,看到一些最初学习时的老代码,回忆往日的时光,还颇有一些感慨呢...以后有空就选一些贴贴,也不怕人笑了。今天第一帖,代码原是大二时为NT4系统写的,是原先实践x86体系写的,作用是在Driver中“调用”用户态的MessageBoxA做出显示。朋友都说:“你无聊不无聊,好多人写过这个题目了”,呵呵,我只是把以前的东西贴贴,尽量少提及别人说过的,可能初学者们会有收获呢。现在作了一点点修改,只在2000上测了测,还可以跑跑。
这就是一个Ring0 Call Ring3的问题。对于这个问题,在原先试验之前网上就有一些讨论了,有了一些替代方案,比如说User APC。
记得见过最早的是应该是Anatoly Vorobey在某新闻组的发言,查了查,他发帖是97年的时候,很古老了。最近www.rootkit.com贴出了一篇关于ring0创建进程 的文章用的就是这个方法,不过仅是其一个简单应用。
UserAPC的代码网上很多。就不贴了,使用很方便很简单,只是注意用时对Thread->ApcState.UserApcPending的处理。
如果我们把处理控制的直接转移作为“调用”的基本要求,那么
依赖于系统间接转移的APC机制就算不上“调用”。那么Ring3代码如何“调用”Ring0代码呢?方法是显然的,我们模拟这样一个场景:系统通过某种机制(比如中断或是改变特权的调用)由ring3进入了
ring0时候的现场(主要是栈现场)。于是我们模拟好后,直接通过返回指令达到直接控制转移的目的。当然,我们应当保存原始现场,以便用户台代码执行完毕后能顺利回到“调用”指令后的第一条指令执行(如同真正的call)。
实质上windows自己也在用这个方法来进行一些有必要的核心态向用户态的直接控制转移,即KeUserModeCallback。典型的例子就是wind32k中的使用,“防止消息钩子注入”里也简单提到。
当时2000还没出来,研究的比较多的是linux和9x的核,对于NT使用此回调的具体过程就不甚清楚,现在源码都漏了颇久了,初学者们看起来方便多了。下面我们自己不利用NT的代码,自己做一个类似的东西。
下面仅仅讨论直接“调用”的基本方法。ring0转向ring3之前首先要确保用户空间的合法性以及ring3代码与用户栈的合法性,这一点根据需求会有许多做法,为了简单起见,调用的时机选在ring3使用DeviceIoControl进入驱动例程时回调,回调的地址与用户栈均由应用程序传入,这样使预处理最小化。

驱动程序分派例程里只需写:

switch(IoControlCode)
{
case IOCTL_CALL_RING3:
{
addr = *PULONG(InputBuffer); //ring3函数地址
stack = *(PULONG(InputBuffer)+1);//ring3栈地址
cfunc();
return 0;
}
}

其中cfunc函数即完成了向ring3的调用,其代码如下(很老的代码,很凌乱,加了点注释):

void __declspec(naked) cfunc()
{
_asm pushad
_asm sidt buffer
IdtEntry = (PIdtEntry_t)Idtr->Base;
OldEntry = IdtEntry[HOOKINT]; //#define HOOKINT 0xF0
_asm lea eax,interrupt
_asm mov NewHandler,eax
/*接管中断0xF0,目的是让应用程序能通过使用int 0f0h
指令返回到核心态。
int 0f0h起的作用正是等同于ret
F0陷阱的处理函数恢复内核栈等至“调用”前的状态*/
_asm cli
IdtEntry[HOOKINT].Dpl = 3;
IdtEntry[HOOKINT].Type = 0xF;
IdtEntry[HOOKINT].Present = 1;
IdtEntry[HOOKINT].OffsetLow = (unsigned short)NewHandler;
IdtEntry[HOOKINT].OffsetHigh = /
(unsigned short)((unsigned int)NewHandler>>16);
_asm sti
_asm {
str word ptr[tr]
push eax
sgdt [esp-2]
pop eax
movzx ebx,word ptr[tr]
and ebx,0fffffff8h
add eax,ebx
mov ebx,[eax]
and ebx,0ffff0000h
shr ebx,16
mov ecx,[eax+4]
and ecx,0ffh
shl ecx,16
or ebx,ecx
mov ecx,[eax+4]
and ecx,0ff000000h
or ebx,ecx
mov tss,ebx
mov cur,esp
}
count=tss->esp0-cur;
/*上面代码获取当前内核栈的地址与需保存大小
下面代码保存栈内容*/
_asm{
mov ecx,count
mov edi,TMP
mov esi,cur
rep movsb
}
/*模拟返回环境,不用多解释了
iretd我们把它类比于call*/
_asm{
mov eax,3bh
mov fs,ax
mov eax,23h
push eax
mov eax,stack
push eax
pushfd
mov eax,1bh
push eax
mov eax,addr
push eax
iretd
}
/*int 0f0h后返回这里开始执行*/
interrupt:
_asm{
mov eax,30h
mov fs,ax
mov ecx,count
mov esi,TMP
mov edi,cur
rep movsb
mov esp,cur
}
IdtEntry=(PIdtEntry_t)Idtr->Base;
_asm cli
IdtEntry[HOOKINT] = OldEntry;
_asm sti
_asm popad
_asm ret
}

基本方法十分简单,具体使用需要的预处理就比较繁琐了。
它可能并不实用,不过可以为一些朋友提供练手机会。
被调用的用户代码就很简单了:

void __declspec(naked) FuncAddr()
{
MessageBox(NULL, "OK","OK",MB_OK);
_asm int 0xF0 //ret
}

...
{
...
BOOL result;
ULONG param[2];
DWORD BytesReturned;
char *stack = (char*)malloc(0x10000);
param[0] = (DWORD)FuncAddr;
param[1] = (DWORD)(stack+0x10000);
result = DeviceIoControl(
hDevice,
IOCTL_CALL_RING3,
param,
8,
0,
0,
&BytesReturned,
0
;
free(stack);
...
}

ring0的驱动程序就这样“调用”了ring3的FuncAddr并显示出了
对话框。
理解这些之后,有兴趣可以看看windows是如何利用这个手段的,
它又复杂在哪点。
最后说一句的是,因为我们的处理过于简单,如果你在ring3的函
数里发生了异常,或是结束进程,那么效果是这个进程会成为清不掉的
“僵尸”进程,可能一看“清不掉”,有的朋友又想到了可不可以利用
来实现“进程不死术”,呵呵,会失望的。僵尸不同于不死,自己看看
吧。
上面是PJF老大的帖子,下面是我根据他的做的例子,我发现通过MALLOC来分配的RING3堆栈在你FREE的时候会异常,可能堆栈的数据信息被破坏了,所以只能用静态数据区来代替下,大家也测试看看
注意的是在输入缓冲区大小的时候应该>=8,因为我们把RING3的地址和堆栈都传入到RING0去执行了.
http://www.driverdevelop.com/forum/html_88451.html?1110610534http://www.driverdevelop.com/forum/upload/wowocock/2005-03-12_CallMsgRing0.rar

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
冰刃IceSword 1.22 简介 IceSword是一斩断黑手的利刃(所以取这土名,有点搞e,呵呵)。它适用于Windows 2000/XP/2003/Vista操作系统,用于查探系统中的幕后黑手(木马后门)并作出处理,当然使用它需要用户有一些操作系统的知识。 在对软件做讲解之前,首先说明第一注意事项 :此程序运行时不要激活内核调试器(如softice),否则系统可能即刻崩溃。另外使用前请保存好您的数据,以防万一未知的Bug带来损失。 IceSword目前只为使用32位的x86兼容CPU的系统设计,另外运行IceSword需要管理员权限。 如果您使用过老版本,请一定注意,使用新版本前要重新启动系统,不要交替使用二者。 IceSword内部功能是十分强大的。可能您也用过很多类似功能的软件,比如一些进程工具、端口工具,但是现在的系统级后门功能越来越强,一般都可轻而易举地隐藏进程、端口、注册表、文件信息,一般的工具根本无法发现这些“幕后黑手”。IceSword使用大量新颖的内核技术,使得这些后门躲无所躲。 如何退出IceSword:直接关闭,若你要防止进程被结束时,需要以命令行形式输入:IceSword.exe /c,此时需要Ctrl+Alt+D才能关闭(使用三键前先按一下任意键)。 如果最小化到托盘时托盘图标又消失了:此时可以使用Ctrl+Alt+S将IceSword主界面唤出。因为偷懒没有重绘图标,将就用吧^_^。 您无须为此软件付费,但如果您使用时发现了什么Bug,请mail to me:jfpan20000@sina.com ,十分感谢。 更新说明: 1.20:(1)恢复了插件功能,并提供一个文件注册表的小插件,详见FileReg.chm;(2)对核心部分作了些许改动,界面部分仅文件菜单有一点变化。 1.20(SubVer 111E3):添加对32位版本Vista(NtBuildNumber:6000)的支持。 1.22:(1)增加普通文件、ADS、注册表、模块的搜索功能;(2)隐藏签名项;(3)添加模块的HOOK扫描;(4)核心功能的加强。
### 回答1: "Ring road" problem is a classic problem in computer science, which involves finding the shortest path that visits all the nodes in a graph. In the case of a ring road, the graph is a simple cycle, and the problem is to find the shortest Hamiltonian cycle. Here is an example C++ code for solving this problem using the Brute-force approach: ``` #include<bits/stdc++.h> using namespace std; const int MAXN = 10; int n, ans = INT_MAX; int G[MAXN][MAXN]; void dfs(int cur, int cost, int vis) { if(vis == (1 << n) - 1) { // all nodes have been visited ans = min(ans, cost + G[cur][0]); return; } for(int i = 0; i < n; i++) { if(!(vis & (1 << i))) { // i-th node has not been visited dfs(i, cost + G[cur][i], vis | (1 << i)); } } } int main() { cin >> n; for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { cin >> G[i][j]; } } dfs(0, 0, 1); cout << ans << endl; return 0; } ``` The main idea of this code is to use depth-first search (DFS) to try all the possible paths, and find the shortest one. The `dfs` function takes three parameters: the current node `cur`, the cost so far `cost`, and a bit vector `vis` which keeps track of which nodes have been visited. The base case is when all nodes have been visited, we update the answer if the current path is shorter than the previous best. In the recursive case, we try all the unvisited nodes, and recursively call `dfs` with the updated parameters. Finally, we call `dfs` with the starting node `0`, cost `0`, and set the first bit of `vis` to `1` to represent that the first node has been visited. ### 回答2: "Ring Road C"是一个指环路C的名称。指环路是一种环状的道路系统,通常围绕城市或地区。在很多大城市都可以找到不止一个环状道路,不同的环路可能有不同的名称,以便进行区分。 指环路C通常表示城市周围的第三个环路,有时也称为城市环线或外环。它通常位于离市中心较远的地区,连接主要的交通枢纽和郊区。指环路C的主要作用是分流穿越城市的交通流量,减少市区拥堵。 指环路C通常是一条较宽的高速公路,具有多个车道和出入口。它连接周边的主要城市、郊区以及通往市区的道路。该环路可以快速方便地将车辆从郊区引入市区,同时也可以将车辆从市区引出,以减轻市区的交通负担。 此外,指环路C也是城市规划的一部分。在城市建设时,规划者通常会考虑到城市未来的发展需求,并预留足够的空间来建设环路C。这样可以方便未来城市的扩张和道路网络的完善,并提供更好的交通条件。 总之,指环路C是城市周围的第三条环状道路,它在城市交通中扮演着重要的角色。通过分流交通流量和便捷地连接郊区和市区,指环路C能够减轻市区的交通压力,并提供更好的交通条件。 ### 回答3: ring road c 是指C环形路,也称为环城高速公路,它是一条环绕城市的高速公路。环城高速公路是一种重要的城市交通设施,通常用于连接主要城市区域,减少交通拥堵,提高交通效率。 C环形路的建设有许多好处。首先,C环形路可以分流城市内部的交通流量,减轻主要道路的压力,减少堵车现象。这样可以提高交通运输效率,节约人们的时间。其次,环形路可以缩短城市内部的距离,方便市民之间的交流和商业活动的发展,促进城市的经济繁荣。此外,环形路还可以为城市提供更好的交通服务,方便居民出行,提升城市形象和品质。 当然,建设环城高速公路也会面临一些挑战和问题。首先,环城高速公路的建设需要占用大量土地资源,可能会引起环境问题和土地利用冲突。其次,建设过程中可能会影响到周边居民的正常生活和工作。因此,在规划和建设环城高速公路时,需要考虑到相关方面的权益和环境保护问题,确保公共利益的最大化。 总的来说,C环形路的建设对城市发展和交通运输有着重要的意义。它是连接城市区域的重要交通枢纽,可以提高交通运输效率,促进经济发展,改善市民生活质量。然而,在建设过程中需要充分考虑到环保和社会效益,确保最大限度地实现公共利益。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值