首页
社区
课程
招聘
大家看看这篇文章是否已经翻译过了,还有翻译的价值么?
发表于: 2006-12-4 20:37 7610

大家看看这篇文章是否已经翻译过了,还有翻译的价值么?

2006-12-4 20:37
7610
关于anti-debugging的
1. - Using the API function CreateFileA to check for the presence of the SoftICE vxd/sys device or its display driver (\\.\SICE, \\.\SIWDEBUG, \\.\SIWVID, \\.\NTICE in Windows NT). This method is now very well known, although you could try using _lread() instead (ASProtect). Some protectors also check for the presence of well known debugging and monitoring utilities for example (\\.\SuperBPMDev0, \\.\TRW, \\.\FILEVXD, \\.\FILEMON, \\.\REGVXD, \\.\REGMON).

Bypass by bpx CreateFileA (change API result) or HEX edit the strings from the detection or patch your nmtrans.dll / Winice.exe against them. (Seen in Advanced Disk Catalog v1.16, MeltICE, Hardlock/HASP envelope).

Another variation of this trick is to check if the NTice service is running using OpenServiceA

2. - INT 41h Debugger Notification.

PUSH EDI
PUSH 0000004F
PUSH 002A002A
CALL Kernel32_1 <-- ORD_1 or VxdCall.
SUB AX,F386
POP EDI
JZ SoftICE_is_running

This detection pushes 002A002A as a parameter, the high 2A means we are calling VWIN_32 vxd, the low 2A the INT 41 dispatch service. Bypass with bpint 30 if ax==0xF386 and clear AX, described in Matt Pietrek's legendary book.

3. - Issue commands to SoftICE. This was one detection I uncovered whilst running an installation program protected by a Hardlock dongle (HASP wrappers also use it). I had inadvertently enabled INT 3's with SoftICE's I3HERE toggle.

:? 4647
00004647 0000017991 "FG" <-- Magic Val. 1.
:? 4A4D
00004A4D 0000019021 "JM" <-- Magic Val. 2.

28F1:0092 MOV SI,4647
28F1:0095 MOV DI,4A4D
28F1:0098 PUSH CS
28F1:0099 POP DS
28F1:009A MOV AX,0911h <-- Function 0911.
28F1:009D MOV DX,000Eh <-- Points at null-terminated command (in this case HBOOT).
28F1:00A0 INT 3 <-- Call Interrupt.

Evidently there are several easy ways to beat this, changing SoftICE's magic values is one option (as described by The_Owl), another would be editing DI/SI or modifying the string at DX, you could also just NOP the INT 3 altogether, this detection routine works with varying levels of success. Other subfunctions exist (0910h, 0912h, 0913h & 0914h) which can be used to manipulate SoftICE breakpoints. In Windows 2000 calling this function with EDX pointing to a garbage string will reboot the computer in the presence of NTICE.

0910h - Display string in SoftICE window.
0911h - Execute commands (DS:DX).
0912h - Get breakpoint information.
0913h - Set SoftICE breakpoints.
0914h - Remove SoftICE breakpoints.

As a trivia aside, the FGJM interface likely represents the initials of the 2 founding members of NuMega (Frank Grossman & Jim Moskun).

Another set of magic values are also known ('BCHK'), this is the (un)documented BoundsChecker interface, if you place BCHK into EBP and set EAX=4 calling INT 3 will return AL=0 in the presence of Winice (works in Windows).

MOV EBP, 04243484Bh <-- 'BCHK'.
MOV AX, 4h
INT 3 <-- Trap debugger.
CMP AL, 4
JNZ SoftICE_is_here

4. - ICECream detection (Windows 95).

Get the Interrupt Descriptor Table (IDT) with the SIDT command.
Get the address of Interrupt gate 1.
Move 16 bytes back.
Check if byte is 1Eh - if so SoftICE is running.

SIDT FWORD PTR opIDT <-- Store IDT.
MOV EAX, DWORD PTR [opIDT+2] <-- EAX=IDT.
ADD EAX, 8h <-- EAX has INT 1 vector.
MOV EBX, [EAX] <-- EBX=INT 1 vector.
ADD EAX, 10h <-- EAX points at INT 3 vector.
MOV EAX, [EAX] <-- Get EAX=INT 3 vector.
AND EAX, 0FFFFh
AND EBX, 0FFFFh <-- Remove selectors.
SUB EAX, EBX <-- Find displacement.
CMP EAX, 01Eh
JZ SoftICE_3.0_is_running

Some programs fetch the offset between INT 1 & INT 3 during small unpacking routines, thus, if SoftICE is running, or in your version of Windows the displacement is different to 10h, it crashes.

5. - Detect SoftICE VxD or SoftICE GFX VxD (obviously ineffective under NT).

XOR DI,DI <-- Clear DI.
MOV ES,DI
MOV AX, 1684h
MOV BX, 0202h <-- VxD ID for SoftICE.
INT 2Fh
MOV AX, ES <-- VxD Entry Point.
ADD DI, AX
CMP DI, 0
JNZ SoftICE_is_here

The GFX id code is identical to that shown above except AX=1684h & BX=7A5Fh.

6. - Detect WinICE handler using INT 68h (V86) since SoftICE hooks it for its own use.

MOV ECX, 0
MOV CX, CS
XOR CL, CL
JECX _dont_use_this_method
MOV AH, 43h
INT 68h
CMP AX, 0F386h <-- Will be set by all system debuggers.
JZ SoftICE_is_here

_dont_use_this_method:

If a debugger is not present AX will be 4300h.

Also one can check the interrupt descriptor table and see if there is a handler installed for INT 68h.

XOR AX, AX
MOV ES, AX
MOV BX, WORD PTR ES:[68h*4]
MOV ES, WORD PTR ES:[68h*4+2]
MOV EAX, 0F43FC80h
CMP EAX, DWORD PTR ES:[EBX]
JNZ SoftICE_is_here

7. - Detect and crash SoftICE with an illegal form of the instruction CMPXCHG8B (LOCK prefix) - opcode: F0 0F C7 C8 (LOCK CMPXCHG8B EAX).

8. - Searching for names installed by SoftICE in low-memory, "WINICE.BR", "SOFTICE1" + others (described in Stone's code below).

9. - Using the control or debug registers - I remember reading somewhere (perhaps in a fairly old Anti-debugging FAQ) that SoftICE doesn't decode instructions pertaining to the control register CR4, you could also play with the debug registers too (clearing any breakpoints is a favoured trick of protection authors). Note : In order to implement any trick using these registers you are going to have to either write a driver (ring 0) or install and trigger your own thread SEH handler, this is not a trick to be used likely, however it is very effective.

10. - Dongle protection (used by dongle SSI Win32 Aegis).

xxxx: xxxx
EB01: JMP $+1
E8: DB E8h
xxxx: xxxx

SoftICE View:

xxxx: xxxx
EB01: JMP $+1
E8xxxxxxxx: CALL bad

TRW (not affected):

xxxx: xxxx
EB01E8: NOP
xxxx: xxxx

11. Calling the Windows function IsDebuggerPresent() (exported from kernel32.dll), returns non-zero in the presence of a debugger, implemented only under NT so not a great trick on its own. A few reversers have already patched their kernel32's against this one and it can be easily patched during runtime using ring 3 APIs.

12. Querying the registry for keys installed by SoftICE, [HKEY_LOCAL_MACHINE/SOFTWARE/NuMega] and subkeys. Far too easy to beat, mine are removed already and the key was NU-MEGA in older versions.

13. Using a timer to check the execution speed of a routine can be an effective way of detecting debuggers, under single step analysis the routine will run much slower, how you choose to react of course is down to your own ingenuity.

14. Check if a potential cracker has set breakpoints on key API functions :-

LEA ESI, GetDlgItemTextA
CALL CheckForSoftICEBP
CMP EAX, "xxxx" <-- Substitute for your own identifier.
JE SoftICEBPIsSet <-- Send bad cracker to some really horrid routine.
CALL ESI

CheckForSoftICEBP:

PUSH ESI
PUSH DS
PUSH CS
POP DS
MOV ESI, [ESI+2] <-- Get dll function jmp address.
MOV ESI, [ESI] <-- Get dll function real address.
MOV EAX, ESI <-- Get first dword of dll function.
AND EAX, 0FFh <-- Use only first byte.
CMP AL, 0CCh <-- INT 3 ?.
MOV EAX, 'xxxx' <-- Your identifier.
JE BPXSet
XOR EAX, EAX <-- No BPX.

BPXSet:

POP DS
POP ESI
RET

This sadly won't detect the cracker who routinely sets breakpoints such as 'bpmb GetDlgItemTextA x'. If you do implement a routine that reads your program from memory be very sure there aren't any alignment 0xCC bytes lurking around.

15. Exploit a W32Dasm bug (this probably won't keep IDA users out but will at least stop the real StringRef crackers which make up the majority).

00401000 JMP 00401005
.
.
.
.
00401005 JMP 00401000

It seems that if this code is placed in a zone that doesn't mess with code flow, it will put W32Dasm in a memory-consuming -> crashing loop. I have to confess I'm not convinced this is actually effective.

16. PROCESSINFOCLASS == ProcessDebugPort, query to see if there is an active process debug port.

PUSH EAX
PUSH 23h
CALL ZwQuerySystemInformation

NTSTATUS NTAPI Nt/ZwQuerySystemInformation (SYSTEMINFOCLASS sic, PVOID pData, DWORD dSize, PDWORD pdSize);

23h -> SYSTEMINFOCLASS == SystemDebuggerInformation and here to see if there is any kernel debugger running.

17. StopIce (anti-SoftICE protection for Delphi applications apparently). I don't want to get at the person who coded the StopIce v1.0 deprotector, but to put it mildly this tool is for people who can't use a HEX editor, included in the archive is my 32 byte example.exe (view it in a HEX editor and have StopIce deprotect and reprotect it), you get the idea ;-).

StopIce detection works via very well known methods, CreateFileA for SICE & NTICE devices. The v1.0 deprotector merely replaces these device names with profane alternatives, all that has changed in v2.0 is non-profane alternatives and a reprotect option. The interesting feature of the protector is its apparent payload (if it actually worked), the program calls GetCurrentProcess() and then ControlService() twice, the first time with 2 missing parameters (thus messing the stack) and the 2nd time with parameters which I assume are just nonsense because of the stack being +8 after the first failed call, the intended payload seems to be a call to ExitWindowsEx. Needless to say if you use FrogsICE/Icedump or even your hex editor this detection is unlikely to be 'stopping any SoftICE' users for longer than about 15 seconds.

18. Detection from SafeDisc (thanks yAtEs for this one).

secdrv.sys, ANDs dr7 with 500, saves the value and checks it for 500.

.text:00010950   mov eax, dr7
.text:0001095C   and eax, 500h
.text:00010961   mov [ecx], eax
Normally without SoftICE, DR7 would have a value of 4xx, for example :

450 AND 500 = 400
412 AND 500 = 400

But SoftICE sets all DR7 values in a 7xx range so :

750 AND 500 = 500
712 AND 500 = 500

So what is SoftICE doing? its setting LE & GE (Global/Local Exact) these are bits 9 & 8 i.e. 1100000000 (0x300), a quick scan of NTICE and we find :

.text:0003BEAC   mov ebx, dr7
.text:0003BEC4   or ebx, 30Ch
.text:0003BECD   mov dr7, ebx
...
.text:0003BEDD   or ebx, 303h
.text:0003BEE6   mov dr7, ebx
..
.text:0003BEF6   or ebx, 330h
.text:0003BEFF   mov dr7, ebx
..
.text:0003BF0F   or ebx, 3C0h
.text:0003BF18   mov dr7, ebx
Patch the .sys to remove 300h.

.text:0003BEAC   mov ebx, dr7
.text:0003BEC4   or ebx, 0Ch
.text:0003BECD   mov dr7, ebx
...
.text:0003BEDD   or ebx, 03h
.text:0003BEE6   mov dr7, ebx
..
.text:0003BEF6   or ebx, 30h
.text:0003BEFF   mov dr7, ebx
..
.text:0003BF0F   or ebx, C0h
.text:0003BF18   mov dr7, ebx
I haven't seen any side effects of doing this. Some older versions have an extra OR at the beginning.

19. Detect single-stepping and turn off the monitor.

MOV DX,3C4 ; Set Port to 3C4 (Sequencer Index Register)
MOV AL,1 ; Set register to access to 1 (Clocking Mode Register)
OUT DX,AL ; Select Clocking Mode Register to be accessed at 3C5
INC DX ; Set DX to 3C5
IN AL,DX ; Get Clocking Mode Register to AL
OR AL,20 ; Set Bit 5
OUT DX,AL ; And rewrite that into the Clocking Mode Register
;
; Bit 5 in the Clocking Mode Register represents:
; Screen Off
; When set to 1, this bit turns off the display
; and assigns maximum memory bandwidth to the
; system. Although the display is blanked, the
; synchronization pulses are maintained. This
; bit can be used for rapid full-screen updates.

a few instructions later ...

MOV DX,3C4 ; Set Port to 3C4 (Sequencer Index Register)
MOV AL,1 ; Set register to access to 1 (Clocking Mode Register)
OUT DX,AL ; Select Clocking Mode Register to be accessed at 3C5
INC DX ; Set DX to 3C5
IN AL,DX ; Get Clocking Mode Register to AL
AND AL,DL ; Reset Bit 5 (AND xxxxxxxx, 11000101)
OUT DX,AL ; And rewrite into the Clocking Mode Register
; Since Bit 5 gets reset, the screen will be turned on
; again.

At runtime everything happens fast enough, whilst during debugging the first sequence simply needs to be skipped otherwise the screen will be turned off. This trick works only on Win9x due to priviledge levels.

20. Exit the program if its being debugged by checking execution timing.

0F31 RDTSC
33C9 XOR ECX,ECX
03C8 ADD ECX,EAX
0F31 RDTSC
2BC1 SUB EAX,ECX
3DFF0F0000 CMP EAX,0FFF
EB08 JB SHORT _FAST_ENOUGH
6A00 PUSH 0 ; ExitCode = 0
E80E060000 CALL <JMP.&KERNEL32.ExitProcess> ; ExitProcess

_FAST_ENOUGH: -> Code continues here

RDTSC is used to retrieve the time stamp counter (number of clocks since boot-up) so this is a time-related trick. When you debug, the distance between those values that are returned in EAX will be higher than those when the program runs without being debugged. So, if there is really a difference you're debugging. The only way around for a cracker is a patch.

21. Anti-tracing trick. More intelligent tracer applications would most likely implement an instruction decoder in order to follow the execution path, of course special handlers will be needed for conditional/unconditional jump instructions as well as others. Another possibility which could fool a tracer is a JMP instruction with a REPE or REPNE prefix. Here is how it works :

REPE (0xF2) <-- prefix only valid with CMPS/SCAS
JMP SHORT LOC_1 (0xEBxx) <-- JMP length is 2

SOME_JUNK_BYTES_HERE

LOC_1:
RESUME_CODE

When the instruction decoder reaches the REPE it correctly decodes the instruction as REPE JMP with an instruction length of 3 bytes. If a special handler routine isn't called the tracer will assume the next instruction to be executed is in the junk bytes and not the JMP to LOC_1. This trick is used by portions of the Armadillo loading code but will only be effective against single step tracers, not those using the trap flag. Armadillo uses a SEH handler to detect if there is a tracer using the trap flag.

22. Anti-IDA trick. I'm not entirely sure if this is a deliberate anti-IDA trick or not, however I recently encounted a file which had the Virtual Size's of its .data section set to an extremely large value, when IDA encountered a 100GB Virtual Size it refused to load the file due to lack of available disk space. Of course this isn't going to stop anyone simply setting the sections Virtual Size to the Raw Size.

23. Under Windows 2000 & Windows XP SoftICE places an INT 3 instruction on the first byte of the function 'UnhandledExceptionFilter' apparently for its own internal use, a protector could well check for its presence.

MOV EDI, UnhandledExceptionFilter
MOV ECX, 6 ; Check the first 6 bytes
MOV AL, 0CCh ; INT 3 opcode
REPNZ SCASB
TEST ECX, ECX
JZ NO_INT3

24. Buffer overflows against OllyDbg.

Format String Bug in OllyDbg 1.10 : http://cert.uni-stuttgart.de/archive/bugtraq/2004/07/msg00211.html
OllyDbg long process Module debug Vulnerability : http://cert.uni-stuttgart.de/archive/bugtraq/2005/03/msg00337.html

25. Detect if running under VMWare (not an anti-debugging measure per se but useful nevertheless since a lot of attackers like VMWare as an environment), if VMWare is running EBX will be non-zero.

MOV EAX, 564D5868h ; 'VMXh'
MOV EBX, 0
MOV ECX, 0Ah
MOV EDX, 5658h ; 'VX'
IN EAX, DX

Top Protection Tips for Software Authors
I'm sure many authors who stumble across reverse engineering sites regard them as little more than 'how to crack' repositories, or terrorist training camps if you want to work for the BSA or DHS. Yes, software piracy does cost most authors a proportion of their potential revenue and I can sympathise with this point of view but try not to let piracy concerns be the be-all and end-all of your life. In the real world of computer software there is probably very little you as an author can do to prevent the really determined pirate from breaking your protection, or not without spending significant sums of time and money, even the ultimate protection can and will be potentially compromised by a legitamate user doing some research.

Preventing the wide scale distribution of cracks for your program can actually be a worthwhile exercise, use a search string such as "warez + crack + your application name" in AltaVista and several of the other engines and you'll probably be able to find out if and where a crack exists for your software. Remember that most 'crack' sites are operated by bored teenagers and hosted on anonymous free space providers, most of these have Piracy@ e-mail addresses that will remove the offending site within a day or 2, just devise your own 'piracy e-mail letter' and send them off at the click of a button.

Below you'll find a collection of protection tips, these won't make your program bullet proof, in fact at best they'll guarantee you not making the worst mistakes and maybe waste a few hours of a crackers time if nothing else, if you want more details regarding implementation drop me an e-mail.

I've always been convinced that knowledge is power, have a read of this piece from Kudzu's World, entitled Piracy and Unconvential wisdom if you are a developer, it might give you some hope.

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

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 846
活跃值: (221)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
2
有点旧,貌似已经有比这个更详细的英文文章的翻译了

一时找不出来
2006-12-8 15:53
0
雪    币: 235
活跃值: (41)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
3

水平太菜,想学习anti,不知道如何学习
呵呵
2006-12-8 19:28
0
雪    币: 846
活跃值: (221)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
4
http://bbs.pediy.com/showthread.php?s=&threadid=36112

最近在收集这些东西中~~~请关注~~~~

http://bbs.pediy.com/showthread.php?s=&threadid=35204

看完这个,你会对不少ANTI有所了解了。

不过最好还是直接看插件。

2004年还是2005年有篇类似的文章,NBW翻译了一部分,忘记还有谁把剩下的部分都翻译了,里面还有简单的VM教学。精华集里可能有,随便找个关键字搜索一下吧。
2006-12-8 21:31
0
雪    币: 235
活跃值: (41)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
5
呵呵,挺有用的
关注...
2006-12-9 10:44
0
游客
登录 | 注册 方可回帖
返回
//