计算机病毒——代码自解密2

计算机病毒——代码自解密2

问题

上一篇博客
上次的程序修改了代码区,因此改变了代码段属性,那么反病毒程序可以通过判断段属性异常来查毒(不是病毒也可能会报毒)。因此我们需要换一个段来存储并运行被加密的代码。

改进

.一般,我们常用的段有:
代码段,可读可执行不可写
数据段,可读可写不可执行
堆栈段,可读可写可执行
因此我们可以选择堆栈段来存储运行。

堆不好操作,而栈操作简单,所以我们分配栈空间。栈需要注意的地方就是栈是从高地址到低地址,与正常顺序正好相反。

这一次实验的基本代码

.386
.model flat, stdcall
option casemap :none

include windows.inc
include user32.inc
include kernel32.inc
include masm32.inc
include gdi32.inc

includelib gdi32.lib
includelib user32.lib
includelib kernel32.lib
includelib masm32.lib
include macro.asm
.data
	lpMsg1		db "I can decrypt myself!",0
	lpMsg2		db "Can you?",0
	
.data?
	buffer	db MAX_PATH dup(?)
	
.CODE
START:
	mov eax,StdOut
	push offset lpMsg1
	call eax
	invoke StdOut,offset lpMsg2
	invoke StdIn,addr buffer,sizeof buffer
	invoke ExitProcess,0
	
end START

编写

我们主要是获取下面代码的机器码

	mov eax,StdOut
	push offset lpMsg1
	call eax

结果

:00401000 B834104000              mov eax, 00401034

* Possible StringData Ref from Data Obj ->"I can decrypt myself!"
                                  |
:00401005 6800304000              push 00403000
:0040100A FFD0                    call eax

机器码是B8341040006800304000FFD0,但是由于StdOut、lpMsg1在接下来的程序中地址会发生改变,因此地址还需运行时获取。
加密并处理得到

	mov ebp,esp
	sub esp,18
	mov BYTE ptr [esp],0B0h
	;mov eax,StdOut
	mov BYTE ptr [esp+5],60h
	;push offset lpMsg1
	mov BYTE ptr [esp+10],0F7h
	mov BYTE ptr [esp+11],0D8h
	;call eax
	mov BYTE ptr [esp+12],60h
	;push Ending
	mov BYTE ptr [esp+17],0C3h
	;ret

这里地址不处理
解密代码后加上

	mov [esp+1],StdOut
	mov DWORD ptr [esp+6],offset lpMsg1
	mov [esp+13],Ending
	
	jmp esp
	
Ending:
	add esp,18
	invoke StdOut,offset lpMsg2
	invoke StdIn,addr buffer,sizeof buffer
	invoke ExitProcess,0

完整代码

.386
.model flat, stdcall
option casemap :none

include windows.inc
include user32.inc
include kernel32.inc
include masm32.inc
include gdi32.inc

includelib gdi32.lib
includelib user32.lib
includelib kernel32.lib
includelib masm32.lib
include macro.asm
.data
	lpMsg1		db "I can decrypt myself!",0
	lpMsg2		db "Can you?",0
	
.data?
	buffer	db MAX_PATH dup(?)
	
.CODE
START:
	mov ebp,esp
	sub esp,18
	mov BYTE ptr [esp],0B0h
	;mov eax,StdOut
	mov BYTE ptr [esp+5],60h
	;push offset lpMsg1
	mov BYTE ptr [esp+10],0F7h
	mov BYTE ptr [esp+11],0D8h
	;call eax
	mov BYTE ptr [esp+12],60h
	;push Ending
	mov BYTE ptr [esp+17],0C3h
	;ret
	
	mov edi,esp
	mov ecx,ebp
	sub ecx,1
	sub ecx,edi
	mov eax,8
	
Decrypt:
	xor [edi],eax
	inc edi
	loop Decrypt
	
	mov [esp+1],StdOut
	mov DWORD ptr [esp+6],offset lpMsg1
	mov [esp+13],Ending
	
	jmp esp
	
Ending:
	add esp,18
	invoke StdOut,offset lpMsg2
	invoke StdIn,addr buffer,sizeof buffer
	invoke ExitProcess,0
	
end START

不过遗憾的是,这个程序只输出了"Can you?"。然而博主在调试后发现程序的确两次进入了Std,且call位置正确,这个问题下次解决。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值