Trao đổi với tôi

http://www.buidao.com

10/14/09

[System Info] PEB & TEB STRUCTURE

Author: Benina
Các sources ví dụ download ở đây:
 
 
1.MỘT SỐ KHÁI NIỆM CƠ BẢN VỀ PROCESS VÀ THREAD.
 
Windows là một hệ điều hành hướng đối tượng, vì vậy chúng ta sẽ tìm hiểu module, process, 
  thread như là một object (đối tượng) của Windows.
Mỗi một file trên disk được load vào trong memory là một module.
Mỗi một process có nhiều modules, vì một process có thể có module là file .exe và các module 
  file .dll “nhập khẩu”.
Mỗi một process có thể có nhiều thread và cũng có thể có một thread duy nhất mà thôi. Nhưng mỗi 1 
  process phải có ít nhất 1 thread.
 
Đối với Windows, để quản lý và thao tác, các process như là một object được mô tả bởi một 
block Executive Process (EPROCESS). Bên trong block này chứa nhiều thuộc tính liên quan đến process. 
Một block EPROCESS chứa và trỏ (point)đến một số các cấu trúc data liên quan khác. Block EPROCESS và 
các cấu trúc liên quan của nó tồn tại trong vùng system address space, với một exception của  
process environment block (PEB) mà nó tồn tại bên trong vùng process address space.(bởi vì nó có thể 
chứa các thông tin được thay đổi bởi user-mode code)
 
Tương tự, một thread sẽ được mô tả bởi một block Executive Thread (ETHREAD). ETHREAD và các cấu trúc 
nó trỏ đến tồn tại bên trong system address space, với một exception của  thread environment block (TEB),
mà nó tồn tại trong vùng process address space.
 
Tóm lại, EPROCESS và ETHREAD nằm trong system address space. Còn PEB và TEB nằm trong process address space. 
Xem hình minh họa sau:

 Phần sau đây chúng ta tìm hiểu về cấu trúc PEB và TEB. -Cấu trúc PEB chứa các dữ liệu mô tả trạng thái của process.-Cấu trúc TEB chứa các dữ liệu mô tả trạng thái của thread.Microsoft khuyến cáo ko nên truy xuất trực tiếp các dữ liệu của các cấu trúc này, vì nó có thể bị thay đổi trong các version tiếp theo của Windows.Nhưng tìm hiểu các thành phần này của các cấu trúc thì vô vùng hấp dẫn. Vì nó giúp ta can thiệp sâu vào hệ điều hành và làm những việc “ko thể tưởng” trong Windows. Nếu các bạn tra cứu MSDN (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/teb.asp )các bạn chỉ tìm được thông tin sau về TEB, còn PEB thì ko thấy nói gì cả . 

TEB

The TEB structure contains data that describes the state of a thread.

typedef struct _TEB {



  
  BYTE Reserved1[1952];



  
  PVOID Reserved2[412];



  
  PVOID TlsSlots[64];



  
  BYTE Reserved3[8];



  
  PVOID Reserved4[26];



  
  PVOID ReservedForOle;



  
  PVOID Reserved5[4];



  
  PVOID TlsExpansionSlots;
} TEB, 



  
*PTEB;

Members

Reserved1

Reserved. Do not access.

Reserved2

Reserved. Do not access.

TlsSlots

Pointer to thread local storage data. Do not directly access.

Reserved3

Reserved. Do not access.

Reserved4

Reserved. Do not access.

ReservedForOle

Reserved for OLE. Do not directly access.

Reserved5

Reserved. Do not access.

TlsExpansionSlots

Pointer to thread local storage expansion data. Do not directly access.

Remarks

You should not directly access this structure. To access the values of the TlsSlots and TlsExpansionSlots members, call TlsGetValue. To access the value of the ReservedForOle member, call CoGetContextToken.

The definition of this structure may change in future versions, so do not assume a maximum size for this structure.

Requirements

Client

Requires Windows Vista, Windows XP, or Windows 2000 Professional.

Server

Requires Windows Server "Longhorn", Windows Server 2003, or Windows 2000 Server.

Header

Declared in Winternl.h.

Do đó chúng ta sẽ tham khảo các hàm này được gọi là Undocumented Functions tại http://undocumented.ntinternals.net/Chúng ta sẽ thấy cấu trúc của PEB và TEB như sau: PEB structure :
PEB structure :
 
typedef struct _PEB {

BOOLEAN InheritedAddressSpace;

BOOLEAN ReadImageFileExecOptions;

BOOLEAN BeingDebugged;

BOOLEAN Spare;

HANDLE Mutant;

PVOID ImageBaseAddress;

PPEB_LDR_DATA LoaderData;

PRTL_USER_PROCESS_PARAMETERS ProcessParameters;

PVOID SubSystemData;

PVOID ProcessHeap;

PVOID FastPebLock;

PPEBLOCKROUTINE FastPebLockRoutine;

PPEBLOCKROUTINE FastPebUnlockRoutine;

ULONG EnvironmentUpdateCount;

PPVOID KernelCallbackTable;

PVOID EventLogSection;

PVOID EventLog;

PPEB_FREE_BLOCK FreeList;

ULONG TlsExpansionCounter;

PVOID TlsBitmap;

ULONG TlsBitmapBits[0x2];

PVOID ReadOnlySharedMemoryBase;

PVOID ReadOnlySharedMemoryHeap;

PPVOID ReadOnlyStaticServerData;

PVOID AnsiCodePageData;

PVOID OemCodePageData;

PVOID UnicodeCaseTableData;

ULONG NumberOfProcessors;

ULONG NtGlobalFlag;

BYTE Spare2[0x4];

LARGE_INTEGER CriticalSectionTimeout;

ULONG HeapSegmentReserve;

ULONG HeapSegmentCommit;

ULONG HeapDeCommitTotalFreeThreshold;

ULONG HeapDeCommitFreeBlockThreshold;

ULONG NumberOfHeaps;

ULONG MaximumNumberOfHeaps;

PPVOID *ProcessHeaps;

PVOID GdiSharedHandleTable;

PVOID ProcessStarterHelper;

PVOID GdiDCAttributeList;

PVOID LoaderLock;

ULONG OSMajorVersion;

ULONG OSMinorVersion;

ULONG OSBuildNumber;

ULONG OSPlatformId;

ULONG ImageSubSystem;

ULONG ImageSubSystemMajorVersion;

ULONG ImageSubSystemMinorVersion;

ULONG GdiHandleBuffer[0x22];

ULONG PostProcessInitRoutine;

ULONG TlsExpansionBitmap;

BYTE TlsExpansionBitmapBits[0x80];

ULONG SessionId;

 
} PEB, *PPEB;
 
Structure PEB (Process Enviroment Block) contains all User-Mode parameters associated by system with current process.
TEB structure:
 
TEB structure:
 
typedef struct _TEB {

NT_TIB Tib;

PVOID EnvironmentPointer;

CLIENT_ID Cid;

PVOID ActiveRpcInfo;

PVOID ThreadLocalStoragePointer;

PPEB Peb;

ULONG LastErrorValue;

ULONG CountOfOwnedCriticalSections;

PVOID CsrClientThread;

PVOID Win32ThreadInfo;

ULONG Win32ClientInfo[0x1F];

PVOID WOW32Reserved;

ULONG CurrentLocale;

ULONG FpSoftwareStatusRegister;

PVOID SystemReserved1[0x36];

PVOID Spare1;

ULONG ExceptionCode;

ULONG SpareBytes1[0x28];

PVOID SystemReserved2[0xA];

ULONG GdiRgn;

ULONG GdiPen;

ULONG GdiBrush;

CLIENT_ID RealClientId;

PVOID GdiCachedProcessHandle;

ULONG GdiClientPID;

ULONG GdiClientTID;

PVOID GdiThreadLocaleInfo;

PVOID UserReserved[5];

PVOID GlDispatchTable[0x118];

ULONG GlReserved1[0x1A];

PVOID GlReserved2;

PVOID GlSectionInfo;

PVOID GlSection;

PVOID GlTable;

PVOID GlCurrentRC;

PVOID GlContext;

NTSTATUS LastStatusValue;

UNICODE_STRING StaticUnicodeString;

WCHAR StaticUnicodeBuffer[0x105];

PVOID DeallocationStack;

PVOID TlsSlots[0x40];

LIST_ENTRY TlsLinks;

PVOID Vdm;

PVOID ReservedForNtRpc;

PVOID DbgSsReserved[0x2];

ULONG HardErrorDisabled;

PVOID Instrumentation[0x10];

PVOID WinSockData;

ULONG GdiBatchCount;

ULONG Spare2;

ULONG Spare3;

ULONG Spare4;

PVOID ReservedForOle;

ULONG WaitingOnLoaderLock;

PVOID StackCommit;

PVOID StackCommitMax;

PVOID StackReserved;

 
} TEB, *PTEB;




Structure TEB (Thread Environment Block) is memory block containing system variables placed in User-Mode memory. Every created thread have own TEB block. User can get address of TEB by call NtCurrentTeb function.

 
Nhưng để chi tiết hơn (có thể dùng kernel debugger để tra cứu) các bạn tham chiếu link sau đây:

http://www.google.com/search?q=cache:C6RbYlPjytwJ:https://www.openrce.org/reference_library/files/reference/Windows%2520Memory%2520Layout,%2520User-Kernel%2520Address%2520Spaces.pdf+NtTIB+Structure&hl=en&ct=clnk&cd=21&client=opera

PEB Structure:

struct _PEB {

0x000 BYTE InheritedAddressSpace;

0x001 BYTE ReadImageFileExecOptions;

0x002 BYTE BeingDebugged;

0x003 BYTE SpareBool;

0x004 void* Mutant;

0x008 void* ImageBaseAddress;

0x00c _PEB_LDR_DATA* Ldr;

0x010 _RTL_USER_PROCESS_PARAMETERS* ProcessParameters;

0x014 void* SubSystemData;

0x018 void* ProcessHeap;

0x01c _RTL_CRITICAL_SECTION* FastPebLock;

0x020 void* FastPebLockRoutine;

0x024 void* FastPebUnlockRoutine;

0x028 DWORD EnvironmentUpdateCount;

0x02c void* KernelCallbackTable;

0x030 DWORD SystemReserved[1];

0x034 DWORD ExecuteOptions:2;

// bit offset: 34, len=2

0x034 DWORD SpareBits:30;

// bit offset: 34, len=30

0x038 _PEB_FREE_BLOCK* FreeList;

0x03c DWORD TlsExpansionCounter;

0x040 void* TlsBitmap;

0x044 DWORD TlsBitmapBits[2];

0x04c void* ReadOnlySharedMemoryBase;

0x050 void* ReadOnlySharedMemoryHeap;

0x054 void** ReadOnlyStaticServerData;

0x058 void* AnsiCodePageData;

0x05c void* OemCodePageData;

0x060 void* UnicodeCaseTableData;

0x064 DWORD NumberOfProcessors;

0x068 DWORD NtGlobalFlag;

0x070 _LARGE_INTEGER CriticalSectionTimeout;

0x078 DWORD HeapSegmentReserve;

0x07c DWORD HeapSegmentCommit;

0x080 DWORD HeapDeCommitTotalFreeThreshold;

0x084 DWORD HeapDeCommitFreeBlockThreshold;

0x088 DWORD NumberOfHeaps;

0x08c DWORD MaximumNumberOfHeaps;

0x090 void** ProcessHeaps;

0x094 void* GdiSharedHandleTable;

0x098 void* ProcessStarterHelper;

0x09c DWORD GdiDCAttributeList;

0x0a0 void* LoaderLock;

0x0a4 DWORD OSMajorVersion;

0x0a8 DWORD OSMinorVersion;

0x0ac WORD OSBuildNumber;

0x0ae WORD OSCSDVersion;

0x0b0 DWORD OSPlatformId;

0x0b4 DWORD ImageSubsystem;

0x0b8 DWORD ImageSubsystemMajorVersion;

0x0bc DWORD ImageSubsystemMinorVersion;

0x0c0 DWORD ImageProcessAffinityMask;

0x0c4 DWORD GdiHandleBuffer[34];

0x14c void (*PostProcessInitRoutine)();

0x150 void* TlsExpansionBitmap;

0x154 DWORD TlsExpansionBitmapBits[32];

0x1d4 DWORD SessionId;

0x1d8 _ULARGE_INTEGER AppCompatFlags;

0x1e0 _ULARGE_INTEGER AppCompatFlagsUser;

0x1e8 void* pShimData;

0x1ec void* AppCompatInfo;

0x1f0 _UNICODE_STRING CSDVersion;

0x1f8 void* ActivationContextData;

0x1fc void* ProcessAssemblyStorageMap;

0x200 void* SystemDefaultActivationContextData;

0x204 void* SystemAssemblyStorageMap;

0x208 DWORD MinimumStackCommit;

};

 

TEB structure

struct _TEB {

0x000 _NT_TIB NtTib;

0x01c void* EnvironmentPointer;

0x020 _CLIENT_ID ClientId;

0x028 void* ActiveRpcHandle;

0x02c void* ThreadLocalStoragePointer;

0x030 _PEB* ProcessEnvironmentBlock;

0x034 DWORD LastErrorValue;

0x038 DWORD CountOfOwnedCriticalSections;

0x03c void* CsrClientThread;

0x040 void* Win32ThreadInfo;

0x044 DWORD User32Reserved[26];

0x0ac DWORD UserReserved[5];

0x0c0 void* WOW32Reserved;

0x0c4 DWORD CurrentLocale;

0x0c8 DWORD FpSoftwareStatusRegister;

0x0cc void* SystemReserved1[54];

0x1a4 int ExceptionCode;

0x1a8 _ACTIVATION_CONTEXT_STACK ActivationContextStack;

0x1bc DWORD SpareBytes1[24];

0x1d4 _GDI_TEB_BATCH GdiTebBatch;

0x6b4 _CLIENT_ID RealClientId;

0x6bc void* GdiCachedProcessHandle;

0x6c0 DWORD GdiClientPID;

0x6c4 DWORD GdiClientTID;

0x6c8 void* GdiThreadLocalInfo;

0x6cc DWORD Win32ClientInfo[62];

0x7c4 void* glDispatchTable[233];

0xb68 DWORD glReserved1[29];

0xbdc void* glReserved2;

0xbe0 void* glSectionInfo;

0xbe4 void* glSection;

0xbe8 void* glTable;

0xbec void* glCurrentRC;

0xbf0 void* glContext;

0xbf4 DWORD LastStatusValue;

0xbf8 _UNICODE_STRING StaticUnicodeString;

0xc00 WORD StaticUnicodeBuffer[261];

0xe0c void* DeallocationStack;

0xe10 void* TlsSlots[64];

0xf10 _LIST_ENTRY TlsLinks;

0xf18 void* Vdm;

0xf1c void* ReservedForNtRpc;

0xf20 void* DbgSsReserved[2];

0xf28 DWORD HardErrorsAreDisabled;

0xf2c void* Instrumentation[16];

0xf6c void* WinSockData;

0xf70 DWORD GdiBatchCount;

0xf74 UChar InDbgPrint;

0xf75 UChar FreeStackOnTermination;

0xf76 UChar HasFiberData;

0xf77 UChar IdealProcessor;

0xf78 DWORD Spare3;

0xf7c void* ReservedForPerf;

0xf80 void* ReservedForOle;

0xf84 DWORD WaitingOnLoaderLock;

0xf88 _Wx86ThreadState Wx86Thread;

0xf94 void** TlsExpansionSlots;

0xf98 DWORD ImpersonationLocale;

0xf9c DWORD IsImpersonating;

0xfa0 void* NlsCache;

0xfa4 void* pShimData;

0xfa8 DWORD HeapVirtualAffinity;

0xfac void* CurrentTransactionHandle;

0xfb0 _TEB_ACTIVE_FRAME* ActiveFrame;

};

Ở đây tôi xin nói thêm về cấu trúc NT_TIB là thành phần đầu tiên trong cấu trúc TEB:

struct _NT_TIB {

0x00 _EXCEPTION_REGISTRATION_RECORD* ExceptionList;

0x04 void* StackBase;

0x08 void* StackLimit;

0x0c void* SubSystemTib;

0x10 void* FiberData;

0x10 DWORD Version;

0x14 void* ArbitraryUserPointer;

0x18 _NT_TIB* Self;

};

Như các bạn thấy cấu trúc này có thành phần cuối:

0x18 _NT_TIB* Seft

Thành phần này dùng để tính base address của cấu trúc NT_TIB và cũng là base address của

TEB vì NT_TIB là cấu trúc con đầu tiên của TEB. Các bạn chú ý điều này.

2.TRUY XUẤT (ASCCESS) TRỰC TIẾP VÀO TEB VÀ PEB:

Theo Mircosoft thì chúng ta ko nên truy xuất vào các cấu trúc này. Nhưng truy xuất (access)

trực tiếp vào nó thì vô cùng thú vị ,rồi các bạn sẽ thấy được điều đó vì tôi cũng nhận thấy

mấy tay viết virus (vx) rất am hiểu các cấu trúc này và đã sử dụng nó cho mục đích phá họai rất hiệu quả.

Muốn truy xuất vào TEB và PEB,đầu tiên ta phải biết base address của các cấu trúc này. Chúng ta

bắt đầu tìm hiểu base addr của các cấu trúc trên.

Windows duy trì cấu trúc TEB và PEB cho mọi thread và process đang thực thi trong hệ thống. Và thanh ghi

đọan FS được set để truy xuất đến cấu trúc TEB của thread đang thực thi. Vậy địa chỉ VA (virual address)

của FS:[0] là base address của TEB.

Việc tính tóan VA (virual address) (ví dụ 0x7FFDE000 là một addr VA)của FS:[0] được Bộ vi xử lý thực hiện.

Vì vậy rất khó khăn để biết được VA của FS:[0] vì do Bộ vi xử lý thực hiện. Nếu chúng ta dùng lệnh:

mov eax, FS:[0]

thì chúng ta chỉ truy xuất được giá trị (value) chứa tại FS:[0] chứ ko phải VA của FS:[0].

Nhưng mai mắn thay, Windows đã hổ trợ chúng ta. Như tôi đã đề cập trong phần cấu trúc NT_TIB, base

address của NT_TIB cũng chính là base address của TEB. Vì vậy, FS:[18h] chứa giá trị base address

của NT_TIB và cũng là base address của TEB. Do đó chúng ta dễ dàng truy xuất base address qua chỉ thị mov:

mov eax,FS:[18h]

Vậy base address của TEB được tham chiếu qua FS:[18h].

Để tìm base address của PEB ta dựa vào cấu trúc TEB , theo cấu trúc TEB ta có:

0x030 _PEB* ProcessEnvironmentBlock;

Vậy tại FS:[30h] chứa base address của PEB.Do đó chúng ta có thể dùng chỉ thị mov để truy xuất base address của PEB.

mov eax,FS:[30h]

Hay chúng ta có thể dùng cặp chỉ thị sau để dựa trên base address của TEB để truy xuất base address của PEB.

mov eax,FS:[18h]

mov eax,dword ptr [eax+30h]

Sau đây chúng ta code một chương trình nhỏ để hiểu những gì đề cập ở trên:

Ví dụ này sẽ hiển thị một hộp thọai thông báo base addr của TEB và PEB trên máy của bạn.

Vidu.asm

.386

.model flat,stdcall

option casemap:none

include \masm32\include\windows.inc

include \masm32\include\kernel32.inc

includelib \masm32\lib\kernel32.lib

include \masm32\include\user32.inc

includelib \masm32\lib\user32.lib

.data

MsgBoxCaption db "PEB & TEB Structure",0

stringout db "Base address TEB (eax=FS:[18h]): %lX ",0dh,0Ah

db "Base address TEB (ecx=d [eax+18h]): %lX",0Dh,0Ah

db "Base address PEB (ebx=FS:[30h]: %lX",0Dh,0Ah

db "Base address PEB (edx=d [eax+30h]): %lX",0Dh,0Ah

db "Value at FS:[0] (esi=FS:[0]): %lX",0Dh,0Ah

db "Value at d [eax] (edi=d [eax]): %lX",0

buffer dd 256 dup (0)

.code

start:

assume fs: nothing

mov eax,fs:[18h]

mov ecx,dword ptr [eax+18h]

mov ebx,fs:[30h]

mov edx,dword ptr [eax+30h]

mov esi, fs:[0]

mov edi, dword ptr [eax]

invoke wsprintf, addr buffer, offset stringout,eax,ecx,ebx,edx,esi,edi

invoke MessageBox, NULL, addr buffer, addr MsgBoxCaption, MB_OK

invoke ExitProcess, NULL

end start

-Trong chương trình trên , có một chỉ thị các bạn cần học, đó là chỉ thị ASSUME, các bạn có thể tham

khảo chỉ thị này phía sau tut.

-Các bạn đọc thêm tut “Windows Memory Management” để hiểu rõ hơn về quản lý bộ nhớ của Windows,

cách chuyển đổi ra VA của Windows. Tôi sẽ public cho các bạn trên web site Benina’s.

3.TÌM HIỂU HÀM ISDEBUGGERPRESENT

Hàm này chỉ đơn giản như sau:

77E72740 > 64:A1 18000000 MOV EAX,DWORD PTR FS:[18]

77E72746 8B40 30 MOV EAX,DWORD PTR DS:[EAX+30]

77E72749 0FB640 02 MOVZX EAX,BYTE PTR DS:[EAX+2]

77E7274D C3 RETN

Chúng ta cùng phân tích nó xem sao.

-Đầu tiên nó lấy base addr của TEB (FS:[18]) lưu vào eax

-Kế đến nó dựa vào base TEB lưu trong eax để tham chiếu đến base addr PEB và lưu vào eax.

-Dựa vào base PEB trong eax,nó sẽ copy một byte tại [eax+2] của cấu trúc PEB vào eax.

Như ta biết theo cấu trúc PEB tại mục 1 có thành phần:

0x002 BYTE BeingDebugged;

vậy tại 0x002 của cấu trúc PEB chứa giá trị xác định chương trình có bị debugging ko.

-Với giá trị trả về trong eax, nếu eax=1 là chương trình đang bị debugging. Nếu eax=0 thì chương trình ko bị debugging.

Các lập trình viên thường sử dụng hàm này để kiểm tra xem chương trình có bị cracker dùng chương

trình debugger để crack ko. Sau đây chúng ta sẽ viết 1 chương trình nhỏ dùng hàm này để kiểm tra debugging.

Vidu1.asm

.386

.model flat,stdcall

option casemap:none

include \masm32\include\windows.inc

include \masm32\include\kernel32.inc

includelib \masm32\lib\kernel32.lib

include \masm32\include\user32.inc

includelib \masm32\lib\user32.lib

include \masm32\m32lib\masm32.inc

includelib \masm32\m32lib\masm32.lib

.data

MsgBoxCaption db "Example IsDebuggerPresent",0

IsDebuggerNonOK db "No Debugging",0

IsDebuggerOK db "DeBugging",0

.code

start:

invoke IsDebuggerPresent

.if eax==0

invoke MessageBox, NULL, addr IsDebuggerNonOK, addr MsgBoxCaption,MB_OK

.elseif

invoke MessageBox, NULL, addr IsDebuggerOK, addr MsgBoxCaption, MB_OK

.endif

invoke ExitProcess, NULL

end start

Sau khi biên dịch ra file exe, các bạn dùng chương trình Olly để debugging file exe của nó xem sao

(nhớ tắt các plugin HideDbg và IsDebugerPresent trong Olly). Nó sẽ hiện thông báo khác với chạy bình

thường ko bị debugging.

Nhưng cách sử dụng hàm này để phát hiện debugging thì quá chuối. Vì các cracker sẽ dùng các plugin dành

cho Olly để defeat hàm này hay set breakpoint tại hàm IsDebuggerPresent và defeat nó dễ dàng.

Bây giờ chúng ta ứng dụng các kiến thức đã học để code 1 chương trình ko dùng hàm này, nhưng chức năng

hòan tòan ko khác so với hàm IsDebuggerPresent.

Vidu2.asm

.386

.model flat,stdcall

option casemap:none

include \masm32\include\windows.inc

include \masm32\include\kernel32.inc

includelib \masm32\lib\kernel32.lib

include \masm32\include\user32.inc

includelib \masm32\lib\user32.lib

include \masm32\m32lib\masm32.inc

includelib \masm32\m32lib\masm32.lib

.data

MsgBoxCaption db "Example IsDebuggerPresent",0

IsDebuggerNonOK db "No Debugging",0

IsDebuggerOK db "DeBugging",0

.code

start:

assume fs: nothing

mov eax,fs:[30h]

movzx eax,byte ptr [eax+2]

.if eax==0

invoke MessageBox, NULL, addr IsDebuggerNonOK, addr MsgBoxCaption,MB_OK

.elseif

invoke MessageBox, NULL, addr IsDebuggerOK, addr MsgBoxCaption, MB_OK

.endif

invoke ExitProcess, NULL

end start

Với chương trình trên (vidu2.asm) thì “anti” good hơn một chút phải ko các bạn.

Đến đây thì các bạn chắc đã hài lòng về những gì mình mới thu thập. Tôi sẽ tiếp tục với đề tài

này trong các lọat tuts sau. Nếu có gì sơ sót mong các bạn góp ý kiến, vì những gì tôi viết ở

đây là những kiến thức tôi thu thập được trên NET, ko 1 ai hướng dẫn, nên chắc chắn rằng sẽ có

sai sót. Mong chỉ giáo.

4.PHỤ LỤC :

A.Anti IsDebuggerPresent discussion

Phần này tôi xin trích bài viết của Kienmanowar trên 4rum REA để cho các bạn tham khảo

thêm về cách defeat hàm IsDebuggerPresent trong Olly.

Link tham chiếu:

http://reaonline.net/forum/showthread.php?t=637&highlight=anti

Kienmanowar:

Anti IsDebuggerPresent discussion - 01-11-2005 , 03:24 PM




Mọi người cho em hỏi nhé........ đừng cười em là được :wub: .

1. Trong quá trình dùng Olly để Debug một chương trình , ta làm sao để có thể phát hiện ra rằng chương trình đó đang sử dụng

hàm API là IsDebuggerPresent để không cho chúng ta thực hiện Debug chương trình đó (trong cả hai trường hợp file đã bị Pack và file chưa bị Pack) ?

Có phải là sau khi ta load file exe (đối với file chưa bị Pack) đó vào trong Olly , khi chúng ta nhấn F9 để run chương trình .

Nhưng sau khi nhấn F9 rồi mà chương trình không Run bình thường mà lại bị Crash ngay hoặc có trường hợp khi nhấn F9 chúng ta

gặp lỗi ACCESS VIOLATION , phải nhấn Shift - F9 n times gì đó để vượt qua đoạn đó nhưng rùi cũng không Run được mà lại bị Terminate.

Vậy đối với những trường hợp này thì khả năng nghi ngờ là chương trình có sử dụng ANTI - Debug là hòan toàn chính xác đúng không ạ?.

Có thể có rất nhiều kiểu chống Anti - Debug khác nhau , nhưng ở đây em chỉ xin tập trung vào hàm API IsDebuggerPresent (kernel32.dll) ?.


2. Với nghi ngờ như trên thì làm thế nào để ta có thể chống lại được phương pháp này ?
Hàm API IsDebuggerPresent là hàm kiểm tra xem có một trình Debug nào đang thực hiện công việc Debug file , nếu như có thì kết quả của

nó sẽ trả về một giá trị khác 0 ngược lại thì không (hiii ngược lại thì tốt quá còn gì :D ) . Vậy nếu như thế chúng ta có thể Patch để thay đồi

lại giá trị trả về đó của hàm này đúng không ?

Vậy thì sẽ có nhưng phương pháp nào để có thể sử dụng trong trường hợp chương trình có sử dụng API IsDebuggerPresent. Theo như tìm

hiểu của em thì có những phương pháp sau hay được sử dụng :

a. Trong Olly , sau khi chúng ta Load chương trình vào xong . Chúng ta sử dụng ngay cái Plugin của Olly là IsDebuggerPresent để tạm thời loại

bỏ anti debug . Nhưng phương pháp này theo em nghĩ nó chỉ dành cho những Newbie chưa biết gì về anti - Debug hoặc những người đã nắm rất rõ về vấn đề này.

b. Ta cũng Load file exe đó vào trong Olly , đợi sau khi load xong . Chúng ta chuyển con trỏ chuột xuống cửa sổ Dump Window.

Tại cửa sổ này , nhấn chuột phải ta chọn Goto --- > Expression (Ctrl + G) . Tiếp theo chúng ta nhập vào là 7FFDF002 và nhấn Ok.

Chọn byte đầu tiên sau đó nhấn Ctrl + E , sửa 01 thành 00 và tiến hành run chương trình một cách bình thường.

c. Cách này cúng giống như trên nhưng chuyên nghiệp hơn đó là , đầu tiên như thường lệ chúng ta Load file exe vào trong Olly. Khi load xong ,

chúng ta nhấn Alt + E để mở cửa sổ Executable . Tại cửa sổ này chúng ta tìm lấy file dll là Kernel32.dll. Nhấn chuột vào file này , sau đó nhấn

chuột phải chọn View Names (or Ctrl + N). Trong cửa sổ Names in kernel32 chúng ta sẽ tìm đến hàm API là IsDebuggerPresent :

Quote:

Names in kernel32, item 542
Address=77E72E92
Section=.text
Type=Export (Known)
Name=IsDebuggerPresent


Đặt một BP tại đây bằng cách nhấn F2. Sau đó chúng ta quay trở lại màn hình chính và nhấn F9 (trong một số trường hợp chúng ta dừng lại

gặp lỗi Exception thì tiếp tục bằng cách nhấn Shift - F9) , chúng ta để ý đến khi nào thanh Status bar có dòng chữ là Breakpoint at kernel32.IsDebuggerPresent

thì là được rùi đó . Chúng ta có thể thấy một đoạn code tương tự như sau :

Code:

77E72E92 > 64:A1 18000000 MOV EAX,DWORD PTR FS:[18]–We are Here
77E72E98 8B40 30 MOV EAX,DWORD PTR DS:[EAX+30]
77E72E9B 0FB640 02 MOVZX EAX,BYTE PTR DS:[EAX+2]
77E72E9F C3


Bây giờ chúng ta nhấn F8 2 times , sau đó nhìn xuống cửa số ngay phía dưới chúng ta sẽ thấy được địa chỉ cần tìm , ghi địa chỉ này lại .

Địa chỉ này không có gì khác chính là địa chỉ mà ở trên đã nói đó là 7FFDF002. Chúng ta chỉ việc thực hiện như cách b là Oki....

Trên đây là một số cách mà em đã tìm hiểu , mọi người có tips & tricks gì hay thì post nhé. Đặc biệt là Anh Moon ...... anh crack nhiều và

chắc chắn gặp không ít soft sử dụng API này..
Mong được sự Support của các anh ........ Thanx nhiều nhiều :wub:

B.PHÁT BIỂU ASSUME

Phần này tôi dịch lại trong phần HELP của MASM. Tôi để nguyên phần tiếng Anh để các bạn đối chiếu cho dễ.

Assume : có nghĩa là thừa nhận, giả định

Assumption : có nghĩa là đảm nhận, đảm trách, hay là giả định

Syntax (Cúpháp) :

ASSUME segregister:seglocation [, segregister:seglocation]...

ASSUME dataregister:qualifiedtype

[, dataregister:qualifiedtype]...

ASSUME register:ERROR [, register:ERROR]...

ASSUME [register:]NOTHING [, register:NOTHING]...

Description (Mô tả):

A general-purpose directive that allows the assembler to determine offsets, select the correct segment register, and verify certain register use assumptions at assembly.

Mục đích tổng quát của chỉ thị này là cho phép assembler xác định offsets, chọn lựa thanh ghi chính xác , và thẩm tra register nào đó sử dụng để đảm trách (assumptions) tại lúc assembly.

The "ASSUME segregister:seglocation" syntax is used to inform the assembler of the current value of . The assembler uses this information to calculate offsets correctly and to guard against segment selection errors. This directive does not generate code to change the value of . The ASSUME directive is not necessary for the CS register, since CS is assumed to the current segment or group automatically. The can be any segment or group name, or an equivalent expression.

Cú pháp "ASSUME segregister:seglocation" syntax này được sử dụng để khai báo cho assembler giá trị hiện hành của . Assembler dùng thông tin này để tính tóan offset một cách chính xác và bảo vệ chống lại các lỗi tuyển lựa đọan (segment selection errors). Chỉ thị này ko sinh ra code để thay đổi giá trị . Chỉ thị ASSUME ko cần thiết cho CS register, khi CS được giả định là segment hiện hành hay group một cách tự động. có thể là bất kỳ segment hay group name, hay một biểu thức tương đương.

The "ASSUME dataregister:type" syntax informs the assembler that is subject to the constraints of . If an assumed register is used incorrectly, the assembler generates an error. The parameter must be the same size as .

Cú pháp "ASSUME dataregister:type" syntax khai báo cho assembler rằng tùy thuộc vào sự ép kiểu . Nếu giả sử một register được dùng ko đúng, assembler sẽ sinh ra một error. Tham số phải giống kích thước như .

ASSUME bx:WORD

mov ax, [bx] ;Error--cannot dereference (tham khảo) non-pointer

ASSUME bx:PTR WORD

mov [bx], 10h ;Assumes operand size is WORD

mov [bx], al ;Error--cannot move byte into word memory

ASSUME al:WORD ;Error--al is only byte-sized

ASSUME bx:BYTE ;Error--bx is word-sized

The ASSUME directive can include ERROR, FLAT, or register:type. MASM 6.1 issues (đưa ra)a warning when you specify ASSUME values for CS other than the current segment or group.

Chỉ thị ASSUME có thể đính kèm ERROR,FLAT, hay register.type. MASM 6.1 đưa ra một cảnh báo khi bạn chỉ định ASSUME các giá trị cho thanh ghi CS khác với segment hiện hành hay group.

The "ASSUME register:ERROR" syntax causes the assembler to generate an error if is later used explictly or implicitly. The OPATTR, .TYPE, and TYPE directives do not cause errors when referring to registers assumed to ERROR.

Cú pháp "ASSUME register:ERROR" syntax làm cho assembler sinh ra một error nếu được sử dụng chậm hơn một cách rõ ràng hoặc một cách hòan tòan. Các chỉ thị OPATTR, .TYPE, và TYPE ko gây ra errors khi tham chiếu đến các registers đã được assumed ERROR.

The "ASSUME register:NOTHING" syntax causes the assembler to remove all assumptions about . ASSUME NOTHING removes all assumptions about all registers.

Cú pháp "ASSUME register:NOTHING" syntax làm cho assember dời bỏ tất cả “các đảm trách” (assumptions) cho . ASSUME NOTHING dời bỏ tất cả các đảm trách (assumptions) cho tất cả các registers.

Use an ASSUME statement each time you load a known value into a segment register. Although not required, the ASSUME directive helps the assembler safeguard against segment selection errors and determine offsets. You may need to use instructions to initialize segment registers properly at run time.

Sử dụng phát biểu ASSUME mỗi khi bạn load một giá trị đã biết vào trong segment register. Mặt dù ko cần thiết, chỉ thị ASSUME giúp assember bảo mật an tòan chống lại các lỗi tuyển lựa đọan (segment selection errors) và xác định các offsets. Bạn có thể cần dùng các chỉ thị này để khởi tạo trị đầu các segment registers một cách thích đáng lúc runtime.

If you use the ASSUME directive to set assumptions about a data register, it will override any assumptions for its subregisters.For example, ASSUME EDX:DGROUP will override assumptions for DL,DH, and DX.

Nếu bạn dùng chỉ thị ASSUME để set đảm trách (assumptions) cho data register, nó sẽ gạt ra bất kỳ “đảm trách” nào cho các subregisters của nó. Ví dụ ASSUME EDX:DGROUP sẽ gạt ra các đảm trách cho DL,DH và DX.

Parameter Description

segregister CS, DS, ES, FS, GS, or SS. The assembler

automatically maintains(duy trì) assumptions(đảm trách) for the CS

segment register.

seglocation A segment address, another segment register, a

group, or FLAT. You can find the segment address

of a label by using the SEG operator (tóan tử). FLAT is

the label of the single FLAT segment.

dataregister Any byte, word, or 32-bit register.

qualifiedtype Any qualified type that will fit in

.

register Any segment or data register.

-o-

http://masm32vn.com (thanz NTA)

http://h1.ripway.com/benina/

http://benina.250free.com

Benina 04/02/2006

Update 04/02/2006

Mail: benina@walla.com

(Không đồng ý bất kỳ ai sử dụng tài liệu này cho mục đích thương mại nếu ko được phép của tác giả)