当前位置:首页 > 代码 > 正文

反调试代码(调试与反调试)[20240506更新]

admin 发布:2024-05-06 17:10 133


本篇文章给大家谈谈反调试代码,以及调试与反调试对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

使用OD时出现请关闭调试或监控工具再试啊。·

被调试的软件有反调试检测代码

不知你使用什么版本的OD。

这里的OD有插件可以隐藏调试器。建议你试试。

Android studio 开发app,如何抵抗动态调试,反调试代码怎么写?请写上详细代码。

为了保护关键代码被逆向分析,一般放在应用程序初始化过程中,如init_array,或jni_onload函数里进行检查代码执行。

1.调试检测

对调试器的检测(ida,gdb,strace, ltrace等调试工具)

a.父进程检测

b.当前运行进程检测

例如对android_server进程检测。针对这种检测只需将android_server改名就可绕过

[objc] view plain copy

pid_t GetPidByName(const charchar *as_name) {

DIR *pdir = NULL;

struct dirent *pde = NULL;

FILEFILE *pf = NULL;

char buff[128];

pid_t pid;

char szName[128];

// 遍历/proc目录下所有pid目录

pdir = opendir("/proc");

if (!pdir) {

perror("open /proc fail.\n");

return -1;

}

while ((pde = readdir(pdir))) {

if ((pde-d_name[0] '0') || (pde-d_name[0] '9')) {

continue;

}

sprintf(buff, "/proc/%s/status", pde-d_name);

pf = fopen(buff, "r");

if (pf) {

fgets(buff, sizeof(buff), pf);

fclose(pf);

sscanf(buff, "%*s %s", szName);

pid = atoi(pde-d_name);

if (strcmp(szName, as_name) == 0) {

closedir(pdir);

return pid;

}

}

}

closedir(pdir);

return 0;

}

c.读取进程状态(/proc/pid/status)

State属性值T 表示调试状态,TracerPid 属性值正在调试此进程的pid,在非调试情况下State为S或R, TracerPid等于0

d.读取 /proc/%d/wchan

下图中第一个红色框值为非调试状态值,第二个红色框值为调试状态:

[objc] view plain copy

static void get_process_status(pid_t pid,const char* info,charchar *outline)

{

FILEFILE *fp;

char filename;

char line = {0};

snprintf( filename, sizeof(filename), "/proc/%d/status", pid );

fp = fopen( filename, "r" );

if ( fp != NULL )

{

while ( fgets( line, sizeof(line), fp ) )

{

if ( strstr( line, info ) )

strcpy(outline,line);

}

fclose( fp ) ;

}

return ;

}

static int getProcessStatus(int pid)

{

char readline = {0};

int result = STATUS_ELSE;

get_process_status(pid,"State",readline);

if(strstr(readline,"R"))

result = STATUS_RUNNING;

else if(strstr(readline,"S"))

result = STATUS_SLEEPING;

else if(strstr(readline,"T"))

result = STATUS_TRACING;

return result;

}

static int getTracerPid(int pid)

{

char readline = {0};

int result = INVALID_PID;

get_process_status(pid,"TracerPid",readline);

charchar *pidnum = strstr(readline,":");

result = atoi(pidnum + 1);

return result;

}

static int getWchanStatus(int pid)

{

FILEFILE *fp= NULL;

char filename;

char wchaninfo = {0};

int result = WCHAN_ELSE;

char cmd = {0};

sprintf(cmd,"cat /proc/%d/wchan",pid);

LOGANTI("cmd= %s",cmd);

FILEFILE *ptr; if((ptr=popen(cmd, "r")) != NULL)

{

if(fgets(wchaninfo, 128, ptr) != NULL)

{

LOGANTI("wchaninfo= %s",wchaninfo);

}

}

if(strncasecmp(wchaninfo,"sys_epoll\0",strlen("sys_epoll\0")) == 0)

result = WCHAN_RUNNING;

else if(strncasecmp(wchaninfo,"ptrace_stop\0",strlen("ptrace_stop\0")) == 0)

result = WCHAN_TRACING;

return result;

}

e. ptrace 自身或者fork子进程相互ptrace

[objc] view plain copy

ptrace me

if (ptrace(PTRACE_TRACEME, 0, 1, 0) 0) {

printf("DEBUGGING... Bye\n");

return 1;

}

void anti_ptrace(void)

{

pid_t child;

child = fork();

if (child)

wait(NULL);

else {

pid_t parent = getppid();

if (ptrace(PTRACE_ATTACH, parent, 0, 0) 0)

while(1);

sleep(1);

ptrace(PTRACE_DETACH, parent, 0, 0);

exit(0);

}

}

f. 防止dump

利用Inotify机制,对/proc/pid/mem和/proc/pid/pagemap文件进行监视。inotify API提供了监视文件系统的事件机制,可用于监视个体文件,或者监控目录。具体原理可参考:- pages/man7/inotify.7.html

伪代码:

[objc] view plain copy

void __fastcall anitInotify(int flag)

{

MemorPagemap = flag;

charchar *pagemap = "/proc/%d/pagemap";

charchar *mem = "/proc/%d/mem";

pagemap_addr = (charchar *)malloc(0x100u);

mem_addr = (charchar *)malloc(0x100u);

ret = sprintf(pagemap_addr, pagemap, pid_);

ret = sprintf(mem_addr, mem, pid_);

if ( !MemorPagemap )

{

ret = pthread_create(th, 0, (voidvoid *(*)(voidvoid *)) inotity_func, mem_addr);

if ( ret = 0 )

ret = pthread_detach(th);

}

if ( MemorPagemap == 1 )

{

ret = pthread_create(newthread, 0, (voidvoid *(*)(voidvoid *)) inotity_func, pagemap_addr);

if(ret 0)

ret = pthread_detach(th);

}

}

void __fastcall __noreturn inotity_func(const charchar *inotity_file)

{

const charchar *name; // r4@1

signed int fd; // r8@1

bool flag; // zf@3

bool ret; // nf@3

ssize_t length; // r10@3

ssize_t i; // r9@7

fd_set readfds; // @2

char event; // @1

name = inotity_file;

memset(buffer, 0, 0x400u);

fd = inotify_init();

inotify_add_watch(fd, name, 0xFFFu);

while ( 1 )

{

do

{

memset(readfds, 0, 0x80u);

}

while ( select(fd + 1, readfds, 0, 0, 0) = 0 );

length = read(fd, event, 0x400u);

flag = length == 0;

ret = length 0;

if ( length = 0 )

{

if ( !ret !flag )

{

i = 0;

do

{

inotity_kill((int)event);

i += *(_DWORD *)event + 16;

}

while ( length i );

}

}

else

{

while ( *(_DWORD *)_errno() == 4 )

{

length = read(fd, buffer, 0x400u);

flag = length == 0;

ret = length 0;

if ( length = 0 )

}

}

}

}

g. 对read做hook

因为一般的内存dump都会调用到read函数,所以对read做内存hook,检测read数据是否在自己需要保护的空间来阻止dump

h. 设置单步调试陷阱

[objc] view plain copy

int handler()

{

return bsd_signal(5, 0);

}

int set_SIGTRAP()

{

int result;

bsd_signal(5, (int)handler);

result = raise(5);

return result;

}

ida伪代码不显示字符串

您想问的是ida伪代码不显示字符串是怎么回事吗?可能是做了反调试处理,使其不显示具体代码。

IDA PRO简称IDA,是一个世界顶级的交互式反汇编工具,有两种可用版本。标准版(Standard)支持二十多种处理器。高级版(Advanced)支持50多种处理器。

IDA PRO不存在任何注册机、注册码或破解版,除了测试版和一个5.0 的免费版外,网络上能下载的都是包含用户许可证的正版,因为所有的安装包都是OEM版,所以IDA官网不提供软件下载,并且软件也没有注册的选项。

c++反调试代码怎么用

很多 加壳,花指令,检测调试器,父进程等等, 但是都比较容易被绕过。

反调试是什么

免杀就不知道了.反调试就是禁止调试一般有这样的一些原理.一、反调试技术反调试技术是一种常见的反检测技术,因为恶意软件总是企图监视自己的代码以检测是否自己正在被调试。为做到这一点,恶意软件可以检查自己代码是否被设置了断点,或者直接通过系统调用来检测调试器。1.断点为了检测其代码是否被设置断点,恶意软件可以查找指令操作码0xcc(调试器会使用该指令在断点处取得恶意软件的控制权),它会引起一个SIGTRAP。如果恶意软件代码本身建立了一个单独的处理程序的话,恶意软件也可以设置伪断点。用这种方法恶意软件可以在被设置断点的情况下继续执行其指令。恶意软件也可以设法覆盖断点,例如有的病毒采用了反向解密循环来覆盖病毒中的断点。相反,还有的病毒则使用汉明码自我纠正自身的代码。汉明码使得程序可以检测并修改错误,但是在这里却使病毒能够检测并清除在它的代码中的断点。2.计算校验和恶意软件也可以计算自身的校验和,如果校验和发生变化,那么病毒会假定它正在被调试,并且其代码内部已被放置断点。VAMPiRE是一款抗反调试工具,可用来逃避断点的检测。VaMPiRE通过在内存中维护一张断点表来达到目的,该表记录已被设置的所有断点。该程序由一个页故障处理程序(PFH),一个通用保护故障处理程序(GPFH),一个单步处理程序和一个框架API组成。当一个断点被触发的时候,控制权要么传给PFH(处理设置在代码、数据或者内存映射I/O中的断点),要么传给GPFH(处理遗留的I/O断点)。单步处理程序用于存放断点,使断点可以多次使用。3.检测调试器在Linux系统上检测调试器有一个简单的方法,只要调用Ptrace即可,因为对于一个特定的进程而言无法连续地调用Ptrace两次以上。在Windows中,如果程序目前处于被调试状态的话,系统调用isDebuggerPresent将返回1,否则返回0。这个系统调用简单检查一个标志位,当调试器正在运行时该标志位被置1。直接通过进程环境块的第二个字节就可以完成这项检查,以下代码为大家展示的就是这种技术:mov eax, fs:[30h]move eax, byte [eax+2]test eax, eax jne @DdebuggerDetected在上面的代码中,eax被设置为PEB(进程环境块),然后访问PEB的第二个字节,并将该字节的内容移入eax。通过查看eax是否为零,即可完成这项检测。如果为零,则不存在调试器;否则,说明存在一个调试器。如果某个进程为提前运行的调试器所创建的,那么系统就会给ntdll.dll中的堆操作例程设置某些标志,这些标志分别是FLG_HEAP_ENABLE_TAIL_CHECK、FLG_HEAP_ENABLE_FREE_CHECK和FLG_HEAP_VALIDATE_PARAMETERS。我们可以通过下列代码来检查这些标志:mov eax, fs:[30h]mov eax, [eax+68h]and eax, 0x70test eax, eaxjne @DebuggerDetected在上面的代码中,我们还是访问PEB,然后通过将PEB的地址加上偏移量68h到达堆操作例程所使用的这些标志的起始位置,通过检查这些标志就能知道是否存在调试器。检查堆头部内诸如ForceFlags之类的标志也能检测是否有调试器在运行,如下所示:mov eax, fs:[30h]mov eax, [eax+18h] ;process heapmov eax, [eax+10h] ;heap flagstest eax, eaxjne @DebuggerDetected上面的代码向我们展示了如何通过PEB的偏移量来访问进程的堆及堆标志,通过检查这些内容,我们就能知道Force标志是否已经被当前运行的调试器提前设置为1了。另一种检测调试器的方法是,使用NtQueryInformationProcess这个系统调用。我们可以将ProcessInformationClass设为7来调用该函数,这样会引用ProcessDebugPort,如果该进程正在被调试的话,该函数将返回-1。示例代码如下所示。push 0

push 4

push offset isdebugged

push 7 ;ProcessDebugPort

push -1

call NtQueryInformationProcess

test eax, eax

jne @ExitError

cmp isdebugged, 0

jne @DebuggerDetected在本例中,首先把NtQueryInformationProcess的参数压入堆栈。这些参数介绍如下:第一个是句柄(在本例中是0),第二个是进程信息的长度(在本例中为4字节),接下来是进程信息类别(在本例中是7,表示ProcessDebugPort),下一个是一个变量,用于返回是否存在调试器的信息。如果该值为非零值,那么说明该进程正运行在一个调试器下;否则,说明一切正常。最后一个参数是返回长度。使用这些参数调用NtQueryInformationProcess后的返回值位于isdebugged中。随后测试该返回值是否为0即可。另外,还有其他一些检测调试器的方法,如检查设备列表是否含有调试器的名称,检查是否存在用于调试器的注册表键,以及通过扫描内存以检查其中是否含有调试器的代码等。另一种非常类似于EPO的方法是,通知PE加载器通过PE头部中的线程局部存储器(TLS)表项来引用程序的入口点。这会导致首先执行TLS中的代码,而不是先去读取程序的入口点。因此,TLS在程序启动就可以完成反调试所需检测。从TLS启动时,使得病毒得以能够在调试器启动之前就开始运行,因为一些调试器是在程序的主入口点处切入的。4.探测单步执行恶意软件还能够通过检查单步执行来检测调试器。要想检测单步执行的话,我们可以把一个值放进堆栈指针,然后看看这个值是否还在那里。如果该值在那里,这意味着,代码正在被单步执行。当调试器单步执行一个进程时,当其取得控制时需要把某些指令压入栈,并在执行下一个指令之前将其出栈。所以,如果该值仍然在那里,就意味着其它正在运行的进程已经在使用堆栈。下面的示例代码展示了恶意软件是如何通过堆栈状态来检测单步执行的:Mov bp,sp;选择堆栈指针Push ax ;将ax压入堆栈Pop ax ;从堆栈中选择该值Cmp word ptr [bp -2],ax ;跟堆栈中的值进行比较Jne debug ;如果不同,说明发现了调试器。 如上面的注释所述,一个值被压入堆栈然后又被弹出。如果存在调试器,那么堆栈指针–2位置上的值就会跟刚才弹出堆栈的值有所不同,这时就可以采取适当的行动。5.在运行时中检测速度衰减通过观察程序在运行时是否减速,恶意代码也可以检测出调试器。如果程序在运行时速度显著放缓,那就很可能意味着代码正在单步执行。因此如果两次调用的时间戳相差甚远,那么恶意软件就需要采取相应的行动了。Linux跟踪工具包LTTng/LTTV通过观察减速问题来跟踪病毒。当LTTng/LTTV追踪程序时,它不需要在程序运行时添加断点或者从事任何分析。此外,它还是用了一种无锁的重入机制,这意味着它不会锁定任何Linux内核代码,即使这些内核代码是被跟踪的程序需要使用的部分也是如此,所以它不会导致被跟踪的程序的减速和等待。6.指令预取如果恶意代码篡改了指令序列中的下一条指令并且该新指令被执行了的话,那么说明一个调试器正在运行。这是指令预取所致:如果该新指令被预取,就意味着进程的执行过程中有其他程序的切入。否则,被预取和执行的应该是原来的指令。7.自修改代码恶意软件也可以让其他代码自行修改(自行修改其他代码),这样的一个例子是HDSpoof。这个恶意软件首先启动了一些异常处理例程,然后在运行过程中将其消除。这样一来,如果发生任何故障的话,运行中的进程会抛出一个异常,这时病毒将终止运行。此外,它在运行期间有时还会通过清除或者添加异常处理例程来篡改异常处理例程。在下面是HDSpoof清除全部异常处理例程(默认异常处理例程除外)的代码。exception handlers before:0x77f79bb8 ntdll.dll:executehandler2@20 + 0x003a

0x0041adc9 hdspoof.exe+0x0001adc9

0x77e94809 __except_handler3exception handlers after:0x77e94809 __except_handler30x41b770: 8b44240c mov eax,dword ptr [esp+0xc]

0x41b774: 33c9 xor ecx,ecx

0x41b776: 334804 xor ecx,dword ptr [eax+0x4]

0x41b779: 334808 xor ecx,dword ptr [eax+0x8]

0x41b77c: 33480c xor ecx,dword ptr [eax+0xc]

0x41b77f: 334810 xor ecx,dword ptr [eax+0x10]

0x41b782: 8b642408 mov esp,dword ptr [esp+0x8]

0x41b786: 648f0500000000 pop dword ptr fs:[0x0] 下面是HDSpoof创建一个新的异常处理程序的代码。0x41f52b: add dword ptr [esp],0x9ca0x41f532: push dword ptr [dword ptr fs:[0x0]0x41f539: mov dword ptr fs:[0x0],esp8.覆盖调试程序信息一些恶意软件使用各种技术来覆盖调试信息,这会导致调试器或者病毒本身的功能失常。通过钩住中断INT 1和INT 3(INT 3是调试器使用的操作码0xCC),恶意软件还可能致使调试器丢失其上下文。这对正常运行中的病毒来说毫无妨碍。另一种选择是钩住各种中断,并调用另外的中断来间接运行病毒代码。下面是Tequila 病毒用来钩住INT 1的代码:new_interrupt_one: push bp mov bp,sp cs cmp b[0a],1 ;masm mod. needed je 0506 ;masm mod. needed cmp w[bp+4],09b4 ja 050b ;masm mod. needed push ax push es les ax,[bp+2] cs mov w[09a0],ax ;masm mod. needed cs mov w[09a2],es ;masm mod. needed cs mov b[0a],1 pop es pop ax and w[bp+6],0feff pop bp iret一般情况下,当没有安装调试器的时候,钩子例程被设置为IRET。V2Px使用钩子来解密带有INT 1和INT 3的病毒体。在代码运行期间,会不断地用到INT 1和INT 3向量,有关计算是通过中断向量表来完成的。一些病毒还会清空调试寄存器(DRn的内容。有两种方法达此目的,一是使用系统调用NtGetContextThread和NtSetContextThread。而是引起一个异常,修改线程上下文,然后用新的上下文恢复正常运行,如下所示: push offset handlerpush dword ptr fs:[0]mov fs:[0],espxor eax, eaxdiv eax ;generate exceptionpop fs:[0]add esp, 4;continue execution;...handler:mov ecx, [esp+0Ch] ;skip divadd dword ptr [ecx+0B8h], 2 ;skip divmov dword ptr [ecx+04h], 0 ;clean dr0mov dword ptr [ecx+08h], 0 ;clean dr1mov dword ptr [ecx+0Ch], 0 ;clean dr2mov dword ptr [ecx+10h], 0 ;clean dr3mov dword ptr [ecx+14h], 0 ;clean dr6mov dword ptr [ecx+18h], 0 ;clean dr7xor eax, eaxret上面的第一行代码将处理程序的偏移量压入堆栈,以确保当异常被抛出时它自己的处理程序能取得控制权。之后进行相应设置,包括用自己异或自己的方式将eax设为0,以将控制权传送给该处理程序。div eax 指令会引起异常,因为eax为0,所以AX将被除以零。该处理程序然后跳过除法指令,清空dr0-dr7,同样也把eax置0,表示异常将被处理,然后恢复运行。9.解除调试器线程我们可以通过系统调用NtSetInformationThread从调试器拆卸线程。为此,将ThreadInformationClass设为0x11(ThreadHideFromDebugger)来调用NtSetInformationThread,如果存在调试器的话,这会将程序的线程从调试器拆下来。以下代码就是一个例子:push 0push 0push 11h ;ThreadHideFromDebuggerpush -2call NtSetInformationThread在本例中,首先将NtSetInformationThread的参数压入堆栈,然后调用该函数来把程序的线程从调试器中去掉。这是因为这里的0用于线程的信息长度和线程信息,传递的-2用于线程句柄,传递的11h用于线程信息类别,这里的值表示ThreadHideFromDebugger。10.解密解密可以通过各种防止调试的方式来进行。有的解密依赖于特定的执行路径。如果这个执行路径没被沿用,比如由于在程序中的某个地方启动了一个调试器,那么解密算法使用的值就会出错,因此程序就无法正确进行自身的解密。HDSpoof使用的就是这种技术。一些病毒使用堆栈来解密它们的代码,如果在这种病毒上使用调试器,就会引起解密失败,因为在调试的时候堆栈为INT 1所用。使用这种技术的一个例子是W95/SK病毒,它在堆栈中解密和构建其代码;另一个例子是Cascade病毒,它将堆栈指针寄存器作为一个解密密钥使用。代码如下所示:lea si, Start ; position to decryptmov sp, 0682 ; length of encrypted bodyDecrypt:xor [si], si ; decryption key/counter 1xor [si], sp ; decryption key/counter 2inc si ; increment one counterdec sp ; decrement the otherjnz Decrypt ; loop until all bytes are decryptedStart: ; Virus body对于Cascade病毒如何使用堆栈指针来解密病毒体,上面代码中的注释已经做了很好的说明。相反,Cryptor病毒将其密钥存储在键盘缓冲区中,这些密钥会被调试器破坏。Tequila使用解密器的代码作为解密钥,因此如果解密器被调试器修改后,那么该病毒就无法解密了。下面是Tequila用于解密的代码:perform_encryption_decryption: mov bx,0 mov si,0960 mov cx,0960 mov dl,b[si] xor b[bx],dl inc si inc bx cmp si,09a0 jb 0a61 ;masm mod. needed mov si,0960 loop 0a52 ;masm mod. needed retthe_file_decrypting_routine: push cs pop ds mov bx,4 mov si,0964 mov cx,0960 mov dl,b[si] add b[bx],dl inc si inc bx cmp si,09a4 jb 0a7e ;masm mod. needed mov si,0964 loop 0a6f ;masm mod. needed jmp 0390 ;masm mod. needed人们正在研究可用于将来的新型反调试技术,其中一个项目的课题是关于多处器计算机的,因为当进行调试时,多处理器中的一个会处于闲置状态。这种新技术使用并行处理技术来解密代码。二、逆转录病毒逆转录病毒会设法禁用反病毒软件,比如可以通过携带一列进程名,并杀死正在运行的与表中同名的那些进程。许多逆转录病毒还把进程从启动列表中踢出去,这样该进程就无法在系统引导期间启动了。这种类型的恶意软件还会设法挤占反病毒软件的CPU时间,或者阻止反病毒软件连接到反病毒软件公司的服务器以使其无法更新病毒库。三、混合技术W32.Gobi病毒是一个多态逆转录病毒,它结合了EPO和其他一些反调试技术。该病毒还会在TCP端口666上打开一个后门。Simile(又名Metaphor)是一个非常有名的复合型病毒,它含有大约14,000行汇编代码。这个病毒通过寻找API调用ExitProcess()来使用EPO,它还是一个多态病毒,因为它使用多态解密技术。它的90%代码都是用于多态解密,该病毒的主体和多态解密器在每次感染新文件时,都会放到一个半随机的地方。Simile的第一个有效载荷只在3月、6月、9月或12月份才会激活。在这些月份的17日变体A和B显示它们的消息。变体C在这些月份的第18日显示它的消息。变体A和B中的第二个有效载荷只有在五月14日激活,而变体C中的第二个有效载荷只在7月14日激活。Ganda是一个使用EPO的逆转录病毒。它检查启动进程列表,并用一个return指令替换每个启动进程的第一个指令。这会使所有防病毒程序变得毫无用处。四、小结本文中,我们介绍了恶意软件用以阻碍对其进行逆向工程的若干反调试技术,同时介绍了逆转录病毒和各种反检测技术的组合。我们应该很好的理解这些技术,只有这样才能够更有效地对恶意软件进行动态检测和分析。

exe病毒的代码是什么?

刚刚看到一个朋友发了一个ff.exe的病毒样本,简单分析了下,第一部分,主函数代码

004061D2 /$ 55 push ebp ; Main

004061D3 |. 8BEC mov ebp, esp

004061D5 |. 81EC 1C030000 sub esp, 31C

004061DB |. 56 push esi

004061DC |. E8 FCAEFFFF call 取当前计算机用户名

004061E1 |. E8 88AFFFFF call 检查沙箱 ; 看自己是不是在虚拟机或沙箱中运行

004061E6 |. 85C0 test eax, eax

004061E8 |. 0F85 2E010000 jnz 0040631C

004061EE |. E8 C3B1FFFF call 检查模块dbghelp.dll ; 检查自己是否被调试

004061F3 |. 84C0 test al, al

004061F5 |. 0F85 21010000 jnz 0040631C

004061FB |. FF15 B8304100 call dword ptr [kernel32.GetCurrentProc; [GetCurrentProcess

00406201 |. 8BF0 mov esi, eax

00406203 |. 56 push esi

00406204 |. E8 DDAFFFFF call 004011E6 ; 调用NativeAPI查询系统信息

00406209 |. 3C 01 cmp al, 1

0040620B |. 59 pop ecx

0040620C |. 75 08 jnz short 00406216

0040620E |. 6A 00 push 0 ; /ExitCode = 0

00406210 |. FF15 FC304100 call dword ptr [kernel32.ExitProcess] ; \ExitProcess

00406216 | 56 push esi ; /hObject

00406217 |. FF15 CC304100 call dword ptr [kernel32.CloseHandle] ; \CloseHandle

0040621D |. E8 63B1FFFF call 00401385 ; 反调试代码

00406222 |. 3C 01 cmp al, 1

00406224 |. 75 08 jnz short 0040622E

00406226 |. 6A 00 push 0 ; /ExitCode = 0

00406228 |. FF15 FC304100 call dword ptr [kernel32.ExitProcess] ; \ExitProcess

0040622E | E8 42140000 call GetAddress ; 动态获取大量API函数地址

00406233 |. 833D 98584100 00 cmp dword ptr [415898], 0

0040623A |. 74 05 je short 00406241

0040623C |. E8 2F360000 call 00409870 ; 调用大量批处理来执行dos命令

00406241 | 8365 F8 00 and dword ptr [ebp-8], 0

00406245 |. 8365 FC 00 and dword ptr [ebp-4], 0

00406249 |. 6A 02 push 2

0040624B |. C745 F0 34594100 mov dword ptr [ebp-10], 00415934 ; ASCII "lncmmmser"

00406252 |. C745 F4 46934000 mov dword ptr [ebp-C], 00409346

00406259 |. FF15 74AA4100 call dword ptr [41AA74] ; kernel32.SetErrorMode

0040625F |. BE 04010000 mov esi, 104

00406264 |. 8D85 E4FCFFFF lea eax, dword ptr [ebp-31C]

0040626A |. 56 push esi ; /BufSize = 104 (260.)

0040626B |. 50 push eax ; |PathBuffer

0040626C |. 6A 00 push 0 ; |/pModule = NULL

0040626E |. FF15 F4304100 call dword ptr [kernel32.GetModuleHandl; |\GetModuleHandleA

00406274 |. 50 push eax ; |hModule

00406275 |. FF15 F8304100 call dword ptr [kernel32.GetModuleFileN; \GetModuleFileNameA

0040627B |. 8D85 ECFEFFFF lea eax, dword ptr [ebp-114]

00406281 |. 56 push esi ; /DestSizeMax = 104 (260.)

00406282 |. 50 push eax ; |DestString

00406283 |. 68 0C594100 push 0041590C ; |SrcString = "%windir%\system"

00406288 |. FF15 BC304100 call dword ptr [kernel32.ExpandEnvironm; \ExpandEnvironmentStringsA

0040628E |. BE 1C594100 mov esi, 0041591C ; ASCII "serivcers.exe"

00406293 |. 8D85 ECFEFFFF lea eax, dword ptr [ebp-114]

00406299 |. 56 push esi ; /%s = "serivcers.exe"

0040629A |. 50 push eax ; |%s

0040629B |. 8D85 E8FDFFFF lea eax, dword ptr [ebp-218] ; |

004062A1 |. 68 40624100 push 00416240 ; |format = "%s\%s"

004062A6 |. 50 push eax ; |s

004062A7 |. FF15 94314100 call dword ptr [msvcrt.sprintf] ; \sprintf

004062AD |. 8D85 ECFEFFFF lea eax, dword ptr [ebp-114]

004062B3 |. 56 push esi

004062B4 |. 50 push eax

004062B5 |. E8 7D3C0000 call CopySelfToSystem32 ; 复制自身到System32目录,并且替换Serivcers.exe

004062BA |. 83C4 18 add esp, 18

004062BD |. 85C0 test eax, eax

004062BF |. 74 35 je short 004062F6

004062C1 |. 8D85 E4FCFFFF lea eax, dword ptr [ebp-31C]

004062C7 |. 6A 01 push 1

004062C9 |. 50 push eax

004062CA |. 68 CB5C4100 push 00415CCB ; ASCII "systemxstuff"

004062CF |. 68 CC5B4100 push 00415BCC ; ASCII "SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions"

004062D4 |. FF35 C85B4100 push dword ptr [415BC8]

004062DA |. E8 7A2E0000 call 00409159 ; 修改关键注册表项,关联病毒为explorer打开文件夹

004062DF |. 8D85 E8FDFFFF lea eax, dword ptr [ebp-218]

004062E5 |. 50 push eax

004062E6 |. E8 F8300000 call 注册系统服务

004062EB |. 83C4 18 add esp, 18

004062EE |. 6A 01 push 1 ; /ExitCode = 1

004062F0 |. FF15 FC304100 call dword ptr [kernel32.ExitProcess] ; \ExitProcess

004062F6 | 68 24624100 push 00416224 ; ASCII "Enabled:Microsoft Enabled"

004062FB |. E8 00ADFFFF call 00401000

00406300 |. 59 pop ecx

00406301 |. 8D45 F0 lea eax, dword ptr [ebp-10]

00406304 |. 50 push eax

00406305 |. FF15 8CAA4100 call dword ptr [41AA8C] ; advapi32.StartServiceCtrlDispatcherA

0040630B |. 85C0 test eax, eax

0040630D |. 75 0D jnz short 0040631C

0040630F |. 8D85 E8FDFFFF lea eax, dword ptr [ebp-218]

00406315 |. 50 push eax

00406316 |. E8 C8300000 call 注册系统服务

0040631B |. 59 pop ecx

0040631C | 33C0 xor eax, eax

0040631E |. 5E pop esi

0040631F |. C9 leave

00406320 \. C2 1000 retn 10

关于反调试代码和调试与反调试的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

标签:

版权说明:如非注明,本站文章均为 AH站长 原创,转载请注明出处和附带本文链接;

本文地址:http://www.ahzz.com.cn/post/1204.html


取消回复欢迎 发表评论:

分享到

温馨提示

下载成功了么?或者链接失效了?

联系我们反馈

立即下载