An alternative method for detecting ollydbg

Source: Internet
Author: User

An alternative method for detecting ollydbg

Author: pumqara

Preface

Nowadays, ring-3 debuggers are increasingly used because they have a graphical interface and are more convenient than ring-0 debuggers (such as SoftICE. In this articleArticleI will show you how to detect ollydbg, one of the best ring-3 debuggers. Many people have heard of isdebugerpresent and FS: [20] detection methods. But is there any other new method? Next I will introduce some of my own detection methods. I will give a detailed explanation, so you can use your imagination to perfect them.

Method 1: findwindow

This method is based on the findwindow function. Like all the dialogs, the Main Dialog Box (window?) of the ollydbg ?) It also has its title and class name. Using this API function, we can determine whether the main ollydbg window is opened. Microsoft writes:

Bytes ------------------------------------------------------------------------------------------------

The findwindow function can obtain the top-level window handle of the window class name or the title is a specific string. This function does not search for subwindows.

Hwnd findwindow (

Lpctstr lpclassname, // address of the window class name

Lptstr lpwindowname // address of the window title

);

Parameter description

Lpclassname

A pointer to a string ending with null that represents the window class name, or an atom that identifies the window class name string. If this parameter is an atom, it must be a global atom pre-created by the globaladdatom function. The 16-bit atom must be placed in the low 8 bits of the lpclassname, and the high 8 bits of the lpclassname must be 0.

Lpwindowname

Pointer to a string ending with null that represents the window name (I .e. the title. If this parameter is null, all windows are considered qualified.

Return Value

If the search is successful, a window handle that meets the search criteria is returned.

If the search fails, the return value is null. To obtain detailed error information, call getlasterror.

Bytes ------------------------------------------------------------------------------------------------

MyProgramParts:

Code:--------------------------------------------------------------------------------

. Data

Strollyclsname DB "ollydbg", 0

. Code

Invoke findwindow, ADDR strollyclsname, null

CMP eax, 00000000 H

JNE olly_detected/

--------------------------------------------------------------------------------

Method 2: createconlhelp32snapshot, process32first/next

This is an interesting method. It is based on four API functions (createquallhelp32snapshot, process32first, process32next, getcurrentprocessid) and a structure (processentry32 ). Let's take a look at what msdn says:

Bytes ------------------------------------------------------------------------------------------------

[Createconlhelp32snapshot]

The createconlhelp32snapshot function creates a snapshot [snapshot] for the specified process (including the heap [heap], module [module], and thread [thread] used by the process).

Handle winapi createconlhelp32snapshot (

DWORD dwflags,

DWORD th32processid

);

Parameter description:

Dwflags

[Input] th32cs_inherit-the snapshot handle can be inherited.

Th32cs_snapall-the snapshot contains all processes and threads in the system, it also includes the heap of the process specified in th32processid and the th32cs_snapheaplist of the module. The snapshot contains all the heap of the process specified in th32processid. List the heap of a process and view heap32listfirst.

Th32cs_snapmodule-the snapshot contains all the modules of the process specified in th32processid. List the modules of the process and view module32listfirst.

Th32cs_snapprocess-the snapshot contains all processes in the system. List all processes and view process32first.

Th32cs_snapthread-the snapshot contains all the threads in the system. List all threads and view thread32first.

Th32processid

[Input] the ID of the process to be crawled. If this parameter is set to 0, the current process is crawled. This parameter is valid only when th32cs_snapheaplist, th32cs_snapmoudle, or th32cs_snapall is set. In other cases, this parameter is ignored and all processes are crawled.

Return values

If the call is successful, the snapshot handle is returned.

If the call fails, invaid_handle_value is returned.

Remarks

The snapshot taken by this function is examined by the other tool help functions to provide their results. access to the snapshot is read only. the Snapshot handle acts like an object handle and is subject to the same rules regarding which processes and threads it is valid in.

List the heap and module status of all processes, specify th32cs_snapall, and set th32processid to 0. Then, for each newly added process in the snapshot, call createconlhelp32snapshot again to set the ID of the new process to be captured and th32cs_snapheaplist or th32cs_snapmoule.

To delete a snapshot, use the closehandle function.

Bytes ------------------------------------------------------------------------------------------------

[Process32first]

Process32first obtains the information of the first process in a system snapshot.

Bool winapi process32first (

Handle hsnapshot,

Lpprocessentry32 lppe

);

Parameter description

Hsnapshot

[Input] handle to the System Snapshot returned when the createconlhelp32snapshot function was previously called

Lppe

[Input, output] pointer to a processentry32 Structure

Return Value

If the first entry in the process list has been copied to the buffer, true is returned. Otherwise, false is returned. If the snapshot does not contain process information, getlasterror will return an error_no_more_files error.

Remarks

The program that calls this function must set the member dwsize in processentry32 to the size of the structure (expressed by the number of nodes ). Process32first changes the dwsize to the number of bytes written to this structure. This value will never be larger than the initial value of dwsize, but it may be smaller. If the value is smaller, any member whose offset is greater than the value is unreliable.

To obtain information about other processes in the same snapshot, use the process32next function.

Bytes ------------------------------------------------------------------------------------------------

[Process32next]

Process32next can get information about the next process in a system snapshot.

Bool winapi process32next (

Handle hsnapshot,

Lpprocessentry32 lppe

);

Parameter description

Hsnapshot

[Input] handle to the System Snapshot returned when the createconlhelp32snapshot function was previously called

Lppe

[Output] pointer to a processentry32 Structure

Return Value

If the next entry in the process list has been copied to the buffer, true is returned. Otherwise, false is returned. If the snapshot does not contain process information, getlasterror will return an error_no_more_files error.

Remarks

To obtain information about the first process in the snapshot, use the process32first function.

Bytes ------------------------------------------------------------------------------------------------

[Processentry32]

After a snapshot is created, processentry32 describes one of a series of processes in the system address space.

Typedef struct tagprocessentry32 {

DWORD dwsize;

DWORD cntusage;

DWORD th32processid;

Ulong_ptr th32defaultheapid;

DWORD th32moduleid;

DWORD cntthreads;

DWORD th32parentprocessid;

Long pcpriclassbase;

DWORD dwflags;

Tchar szexefile [max_path];

} Processentry32, * pprocessentry32;

Member variables

Dwsize

The Structure Size expressed by the number of nodes. Set this member to sizeof (processentry32) before calling process32first ). If you do not initialize dwsize, process32first fails to be called.

Cntusage

The number of times the process is referenced. This process exists only when the number of times referenced by a process is not 0. Once the number of times it is referenced is 0, the process is terminated.

Th32processid

The ID of the process. (ID)

Th32defaultheapid

Identifier of the default heap for the process. the contents of this Member has meaning only to the tool help functions. it is not a handle, nor is it usable by functions other than the toolhelp functions.

Th32moduleid

Module identifier of the process. The contents of this Member has meaning only to the tool help functions. It is not a handle, nor is it usable by funther other than the toolhelp functions.

Cntthreads

The number of threads started by the process.

Th32parentprocessid

Create the identity of the parent process of the process.

Pcpriclassbase

Base priority of any threads created by this process.

Dwflags

Unused, retained

Szexefile

Pointer to a null string that specifies the executable file to which the process belongs.

In Windows ME/98/95, the file name contains the path.

Bytes ------------------------------------------------------------------------------------------------

[Getcurrentprocessid]

Getcurrentprocessid returns the identifier of the process that calls the function.

DWORD getcurrentprocessid (void)

Parameter description:

This function has no parameters.

Return Value

The returned value is the identifier of the process that calls the function.

Remarks

This process identifier (ID) identifies a unique process in the system until the process is terminated.

Bytes ------------------------------------------------------------------------------------------------

Our goal is to check whether the parent process of our program is ollydbg.

Plan:

1) Use getcurrentprocessid to get the process ID of our program.

2) use createconlhelp32snapshot and process32first/next to compare whether the th32processid member in each processentry32 structure is our process id until it is found out.

3) Obtain th32parentprocessid in the processentry32 structure. (Parent process ID)

4.) Use createconlhelp32snapshot to start a new comparison. However, this comparison compares the ID of each th32processid member to the parent process we obtained in step 1 until we can find it.

5.) obtain the szexefile member in processentry32 to see if it is "ollydbg.exe"

6.) If yes, we will know that our program is running under the control of ollydbg.

Sample Code:

Code :--------------------------------------------------------------------------------

. 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", 0 h

Valcurrentpid dd 0

Valparentpid dd 0

Hsnapshot dd 0

. Data?

Proces processentry32 <>

. Code

Start:

; Create a snapshot

Invoke createconlhelp32snapshot, th32cs_snapprocess, null

MoV hsnapshot, eax

Obtain the ID of the current process.

Invoke getcurrentprocessid

MoV valcurrentpid, eax

Lea ESI, offset proces

Assume ESI: PTR processentry32

MoV [esi]. dwsize, sizeof processentry32

; Start the first round of Search

; Use valcurrentpid to find the current process

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

; Create a snapshot again

Invoke createconlhelp32snapshot, th32cs_snapprocess, null

MoV hsnapshot, eax

MoV [esi]. dwsize, sizeof processentry32

; Start the second round of Search

; Use valparentpid to find the parent process of the current process

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

; Extract the file name from the complete path

Lea eax, [esi]. szexefile

Push eax

Invoke lstrlen, eax

Sub eax, 11

Pop EBX

Add EBX, eax

Converts the file name to uppercase, and compares it with "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

--------------------------------------------------------------------------------

Method 3: setunhandledexceptionfilter

The article <seh in ASM> about seh in Hume has a classic discussion. It is omitted here and only lists the code, for more information, see <seh in ASM> and <seh in ASM>)

Code :--------------------------------------------------------------------------------

. 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

Strnotfound DB "ollydbg not found! ", 0

. Code

Excphandler proc

MoV eax, dword ptr [esp + 4]; eax = prediction_pointers

MoV eax, [eax + 4]; eax = Context

Assume eax: PTR Context

MoV [eax]. regeip, offset safe_address; change regeip

Pushad

Invoke MessageBox, 0, ADDR strnotfound, ADDR strcaption, 0

Popad

XOR eax, eax ;\

;) Set prediction_continue_execution

Dec eax ;/

Retn 4; normalize stack and return

Excphandler endp

Start:

Invoke setunhandledexceptionfilter, offset excphandler

MoV EBX, dword ptr [0 ffffffh]; Exception is here!

Safe_address:

Invoke exitprocess, 0

End start

--------------------------------------------------------------------------------

Method 4: API relocation

This is a method I have discovered. It is based on the processing method when ollydbg calls an API function. When the program being debugged calls the API function, Oleh yuschuk (author of ollydbg) uses the API relocation method in its Debugger for processing. The following is an example:

0401000> push asd.00403033;/filename = "kernel32.dll"

00401005 call; \ loadlibrarya

|

|

'--> 0040105c jmp dword ptr ds: [402004]; jmp dword ptr ds: [<& kernel32.loadlibrarya>]

|

|

'--> 87ff4120 push bff776d0; push kernel32.loadlibrarya

87ff4125 JMP kernel32.bff957ca

It seems that he manually loads the input table and fills the IAT manually. All the API addresses are reset to a allocated buffer. In this buffer, he calls a function in a strange way. But here is a more important question: He also imitates the getprocaddress function, so this function returns the relocated address. For example, the actual address of isdebuggerpresent in the memory is bff946f6, but this function returns the address 87ff4110 after the relocation. How can we use this to implement ollydbg detection? Well, there are many methods. The following is the simplest one:

1) load the kernel32.dll library, then it will return its base address (it is loaded to the memory location)

2) Call the getprocaddress function to obtain the exitprocess address.

3) Compare the above return value (the exitprocess address obtained by getprocaddress) with the base address of kernel32.dll.

4.) If the returned value (obtained in step 1) is greater than the base address (obtained in step 2), we can be sure that this API function is directly called. Otherwise, this API is indirectly called.

Example program:

Code :--------------------------------------------------------------------------------

. 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

Strlibrary DB "kernel32.dll", 0

Strfunction DB "exitprocess", 0

. Code

Start:

Invoke loadlibrary, ADDR strlibrary

Push eax; eax is the base address of kernel32.dll

Invoke getprocaddress, eax, ADDR strfunction

; Eax is the exitprocess address or the address after the relocation

Pop EBX; EBX is the base address of kernel32.dll

CMP eax, EBX; Whether to exitprocess address <kernel32.dll base address

Jl olly_detected

Invoke MessageBox, 0, ADDR strnotfound, ADDR strcaption, null

Invoke exitprocess, 0

Olly_detected:

Invoke MessageBox, 0, ADDR strfound, ADDR strcaption, null

Invoke exitprocess, 0

End start

--------------------------------------------------------------------------------

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.