首页
社区
课程
招聘
[译]The other ways to detect OllyDbg 检测OllyDbg的另类方法
发表于: 2004-8-17 15:16 22498

[译]The other ways to detect OllyDbg 检测OllyDbg的另类方法

RoBa 活跃值
16
2004-8-17 15:16
22498

这是linhanshi兄放在他的网站上的,我觉得不错就翻译了下,水平很烂,多多包涵!

The other ways to detect OllyDbg 检测OllyDbg的另类方法

Pumqara作/RoBa[TT]译

前言

现在是2004年了,RING-3级调试器被越来越多地使用,因为它们有图形界面并且比RING-0级调试器(比如SOFTICE)更加方便。在这篇文章中我将讲述如何检测最好的RING-3调试器之一――OllyDbg。许多人都听说过IsDebugerPresent和fs:[20]检测手段,但是有没有其他的新方法呢?下面我向你介绍我自己的一些检测手段。我会给出详细的解释,因此你可以用你自己的想象力来完善它们。

方法一:FindWindow

这个方法是基于FindWindow函数。像所有的对话框一样,OllyDbg的主对话框(窗口?)也有它的标题和类名。使用这个API函数我们可以判断OllyDbg的主窗口是否打开。Microsoft这样写道:
------------------------------------------------------------------------------------------------
FindWindow函数能够获得窗口类名或标题为特定字符串的顶层窗口的句柄。该函数不搜索子窗口。

HWND FindWindow(

LPCTSTR lpClassName, //窗口类名的地址
LPCTSTR lpWindowName //窗口标题的地址
);

参数说明

lpClassName
指向一个以NULL结尾的表示窗口类名的字符串的指针,或者是一个标识窗口类名字符串的atom。如果该参数是一个atom,它必须是被函数GlobalAddAtom预先建立的一个全局atom。这个16位的atom必须放在lpClassName的低8位,lpClassName的高8位必须为0。

lpWindowName
指向一个以NULL结尾的表示窗口名称(即标题)的字符串的指针。如果这个参数为NULL,所有的窗口都被认为是符合条件的。

返回值

如果搜索成功,返回找到的符合条件的窗口句柄。
如果搜索失败,返回值为NULL。要得到详细的错误信息可以调用GetLastError。
------------------------------------------------------------------------------------------------
我的程序片断:

.data
strOllyClsName db "OLLYDBG",0

.code
invoke FindWindow, ADDR strOllyClsName, NULL
cmp eax, 00000000h
jne Olly_Detected/
.586
.model flat, stdcall
option casemap:none
include d:\masm32\INCLUDE\Windows.inc
include d:\masm32\INCLUDE\user32.inc
include d:\masm32\INCLUDE\kernel32.inc
includelib d:\masm32\lib\user32.lib
includelib d:\masm32\lib\kernel32.lib

.data
strCaption db "OllyDbg Detector!",0
strFound db "OllyDbg found!",0
strNotFound db "OllyDbg NOT found!",0
strOllyDbg db "OLLYDBG.EXE",0h
valCurrentPiD dd 0 
valParentPiD dd 0
hSnapShot dd 0

.data?
proces PROCESSENTRY32 <>

.code
start: 
; 建立快照
invoke CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS,NULL
mov hSnapShot,eax

; 得到当前进程ID
invoke GetCurrentProcessId
mov valCurrentPiD,eax

lea esi,offset proces
assume esi:ptr PROCESSENTRY32
mov [esi].dwSize,sizeof PROCESSENTRY32

; 开始第一轮搜索
; 用valCurrentPiD查找当前进程
invoke Process32First,hSnapShot,addr proces

lea esi,offset proces
assume esi:ptr PROCESSENTRY32
mov ebx,valCurrentPiD

cmp ebx,[esi].th32ProcessID
jne nope1

nope1:
invoke Process32Next,hSnapShot,addr proces

lea esi,offset proces
assume esi:ptr PROCESSENTRY32

mov ebx,valCurrentPiD
cmp ebx,[esi].th32ProcessID
jne nope1

push [esi].th32ParentProcessID
pop valParentPiD
invoke CloseHandle,hSnapShot

; 再次建立快照
invoke CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS,NULL
mov hSnapShot,eax

mov [esi].dwSize,sizeof PROCESSENTRY32

; 开始第二轮搜索
; 使用valParentPiD查找当前进程的父进程
invoke Process32First,hSnapShot,addr proces

lea esi,offset proces
assume esi:ptr PROCESSENTRY32
mov ebx,valParentPiD

cmp ebx,[esi].th32ProcessID
jne nope2

nope2:

invoke Process32Next,hSnapShot,addr proces
lea esi,offset proces
assume esi:ptr PROCESSENTRY32
mov ebx,valParentPiD
cmp ebx,[esi].th32ProcessID
jne nope2

; 从完整路径中提取出文件名
lea eax, [esi].szExeFile
push eax
invoke lstrlen,eax
sub eax,11
pop ebx
add ebx,eax

; 把文件名变成大写,与"OLLYDBG.EXE"比较 
invoke CharUpper,ebx
invoke lstrcmp,ebx,addr strOllyDbg

.IF eax==0
invoke MessageBox,0,addr strFound,addr strCaption,0
.ELSE
invoke MessageBox,0,addr strNotFound,addr strCaption,0
.ENDIF

invoke CloseHandle,hSnapShot
invoke ExitProcess,0

end start

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (28)
雪    币: 251
活跃值: (260)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
2
赞 :)
2004-8-17 15:33
0
雪    币: 97697
活跃值: (200829)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
3
辛苦了!
2004-8-17 15:40
0
雪    币: 303
活跃值: (466)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
3q
可是第二种怎么避开??
2004-8-17 18:17
0
雪    币: 339
活跃值: (1510)
能力值: ( LV13,RANK:970 )
在线值:
发帖
回帖
粉丝
5
学习
2004-8-17 18:38
0
雪    币: 241
活跃值: (145)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
辛苦了.
2004-8-17 18:38
0
雪    币: 494
活跃值: (629)
能力值: ( LV9,RANK:1210 )
在线值:
发帖
回帖
粉丝
7
第2种,ACProtect早就在用了,用修改版的OD
就行了(顺便把第1种也解决了)。

第4种没碰到过,不行硬跟好了:D
2004-8-17 20:09
0
雪    币: 241
活跃值: (21)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
第四种好象只有在9X下面才会出现,是系统的造成的,用其他RING3调试器也有这样的情况,不关ODB的事.
一个简单的检测方法是GetProcAddress同一个函数2次,如果出现上面情况的话,2次得到的地址好象应该是不一样的.
不过现在还有谁在9X下面用ODB呢?
2004-8-17 22:33
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
9
9x下的api在共享内存段居然不让下段点,神会去用吧.
2004-8-17 23:44
0
雪    币: 221
活跃值: (55)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
谢谢翻译
2004-8-18 11:11
0
雪    币: 519
活跃值: (1223)
能力值: ( LV12,RANK:650 )
在线值:
发帖
回帖
粉丝
11
我的是98,第四种试过可以,别的就不知道了
2004-8-18 11:11
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
12
最初由 3kkk 发布
第四种好象只有在9X下面才会出现,是系统的造成的,用其他RING3调试器也有这样的情况,不关ODB的事.
一个简单的检测方法是GetProcAddress同一个函数2次,如果出现上面情况的话,2次得到的地址好象应该是不一样的.
不过现在还有谁在9X下面用ODB呢?

我想应该是9x的API都映射在共享内存, Ring-3的Debugger无权修改,所以无法下断.因此都用修改Imports的方法,所以就会出现这个显像.
至于两次GetProcAddress我不明白,是怎么回事?
2004-8-18 16:16
0
雪    币: 186
活跃值: (26)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
第二种其实最好解决了, 你只要把可执行文件的名字改了就行了。。:)
2004-8-19 13:45
0
雪    币: 241
活跃值: (160)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
强啊
2004-8-19 14:40
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
真的是辛苦了!
2004-8-19 22:51
0
雪    币: 383
活跃值: (786)
能力值: ( LV12,RANK:730 )
在线值:
发帖
回帖
粉丝
16
扶持,支持!
2004-8-24 16:02
0
雪    币: 690
活跃值: (1826)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
17
辛苦了,谢谢。
2004-8-26 10:46
0
雪    币: 209
活跃值: (70)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
多谢,第二种最好对付!!:)
2004-8-31 23:40
0
雪    币: 16
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
19
这样也更“人性化”一点,不像FindWindow或者传统的遍历进程一样,发现有调试器不管人家在干什么一律拉出去毙了:D。

=====================
呵呵,呵呵
2004-9-7 11:13
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
不错
2004-10-7 22:12
0
雪    币: 0
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
21
good,thank u.
2004-10-9 02:17
0
雪    币: 409
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
22
多谢!
2004-10-10 11:47
0
雪    币: 258
活跃值: (230)
能力值: ( LV12,RANK:770 )
在线值:
发帖
回帖
粉丝
23
不好,强烈支持~~,太严重了~~~
2004-10-23 11:29
0
雪    币: 61
活跃值: (160)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
24
强烈支持先!!!
2004-12-16 09:57
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
RoBa老大,原文在哪里啊?
2005-1-17 10:35
0
游客
登录 | 注册 方可回帖
返回
//