计算机病毒——代码⾃解密
计算机病毒——代码⾃解密
原理
获取内存中代码段中需解密的⽚段,并解密。
实现
为了⽅便,使⽤xor进⾏加解密,并使⽤密钥为8。需要MASMPlus和W32Dasm。
第⼀个程序代码
这⾥的代码并没有加密,但却在运⾏时解密,因此会运⾏时错误。
.386
.model flat, stdcall
option camap :none
include
include
include
include
include
includelib
includelib
includelib
includelib
include
.data
lpMsg db "I can decrypt mylf!",0
.data?
buffer db MAX_PATH dup(?)
.CODE
START:
mov edi,Virus_start
mov ecx,Virus_end
sub ecx,edi
mov eax,8
Decrypt:
xor [edi],eax
inc edi
loop Decrypt
Virus_start:
push offt lpMsg
call StdOut
;invoke StdOut,offt lpMsg
Virus_end:
invoke StdOut,offt lpMsg
invoke StdIn,addr buffer,sizeof buffer
invoke ExitProcess,0
end START
⽤W32Dasm反编译,需要被加密代码(反汇编略)为
:0040101F 6800304000
:00401024 E828000000
提取机器码:6800304000E828000000
获取加密后的内容
上⼀个C++写的程序来加密这段代码
#include
using namespace std;
typedef unsigned char BYTE;
typedef unsigned int DWORD;
BYTE buff[2];
const BYTE key = 8;
BYTE value;
BYTE scan(BYTE buf[2]);
void print(BYTE x,FILE* f);
int main();
BYTE scan(BYTE buf[2])
{
BYTE tmp=0;
if(buf[0]>='0'&&buf[0]<='9') tmp=buf[0]-'0';
el tmp=buf[0]-'A'+10;
tmp=tmp*16;
if(buf[1]>='0'&&buf[1]<='9') tmp+=buf[1]-'0';
el tmp+=buf[1]-'A'+10;
return tmp;
}
void print(BYTE x,FILE* f)
{
fprintf(f,"tdb ");
BYTE tmp[2];
tmp[0]=x/16;
tmp[1]=x%16;
if(tmp[0]>=0&&tmp[0]<=9) fprintf(f,"%c",tmp[0]+'0');
el fprintf(f,"%c",tmp[0]+'A'-10);
if(tmp[1]>=0&&tmp[1]<=9) fprintf(f,"%c",tmp[1]+'0');
el fprintf(f,"%c",tmp[1]+'A'-10);
fprintf(f,"hn");
}
int main()
{
FILE* f=fopen("","r");
FILE* n=fopen("","w");
while(fread(buff,1,2,f)!=0)
{
value=scan(buff);
value=value^key;
print(value,n);
}
}
把刚才的机器码写⼊中,运⾏这个C++程序,在中得到
db 60h
db 08h
db 38h
db 48h
db 08h
db E0h
db 20h
db 08h
db 08h
db 08h
这是不符合Masm标准的,修改为
db 60h
db 08h
db 38h
db 48h
db 08h
db 0E0h
db 20h
db 08h
db 08h
db 08h
接着替换原来的汇编代码
.386
.model flat, stdcall
option camap :none
include
include
include
include
include
includelib
includelib
includelib
includelib
include
.data
lpMsg db "I can decrypt mylf!",0
.data?
buffer db MAX_PATH dup(?)
.CODE
START:
mov edi,Virus_start
mov ecx,Virus_end
sub ecx,edi
mov eax,8
Decrypt:
xor [edi],eax
inc edi
loop Decrypt
Virus_start:
db 60h
db 08h
db 38h
db 48h
db 08h
db 0E0h
db 20h
db 08h
db 08h
db 08h
;invoke StdOut,offt lpMsg
Virus_end:
invoke StdOut,offt lpMsg
invoke StdIn,addr buffer,sizeof buffer
invoke ExitProcess,0
end START
修改⼯程属性
然⽽,Windows下代码段默认不可写,需要修改段属性。在链接参数后补上 /ction:.text,rw 即可。
(可选)美化源代码
源代码有很多db,不好看,再次使⽤W32Dasm反编译,得到
:00401016 60 pushad
:00401017 0838 or byte ptr [eax], bh
:00401019 48 dec eax
:0040101A 08E0 or al, ah
:0040101C 2008 and byte ptr [eax], cl
:0040101E 0808 or byte ptr [eax], cl
⽤反编译代码替换源代码
.386
.model flat, stdcall
option camap :none
include
include
include
include
include
includelib
includelib
includelib
includelib
include
.data
lpMsg db "I can decrypt mylf!",0
.data?
buffer db MAX_PATH dup(?)
.CODE
START:
mov edi,Virus_start
mov ecx,Virus_end
sub ecx,edi
mov eax,8
Decrypt:
xor [edi],eax
inc edi
loop Decrypt
Virus_start:
pushad
or byte ptr [eax], bh
dec eax
or al, ah
and byte ptr [eax], cl
or byte ptr [eax], cl
;invoke StdOut,offt lpMsg
Virus_end:
invoke StdOut,offt lpMsg
invoke StdIn,addr buffer,sizeof buffer
invoke ExitProcess,0
end START
然⽽,or al,ah 却编译成了0AC4,因此最终代码如下
.386
.model flat, stdcall
option camap :none
include
include
include
include
include
includelib
includelib
includelib
includelib
include
.data
lpMsg db "I can decrypt mylf!",0
.data?
buffer db MAX_PATH dup(?)
.CODE
START:
mov edi,Virus_start
mov ecx,Virus_end
sub ecx,edi
mov eax,8
Decrypt:
xor [edi],eax
inc edi
loop Decrypt
Virus_start:
pushad
or byte ptr [eax], bh
dec eax
db 08h
db 0E0h
and byte ptr [eax], cl
or byte ptr [eax], cl
;invoke StdOut,offt lpMsg
Virus_end:
invoke StdOut,offt lpMsg
invoke StdIn,addr buffer,sizeof buffer
invoke ExitProcess,0
end START
运⾏结果
本文发布于:2023-05-22 20:49:39,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/zhishi/a/168475977949442.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:计算机病毒——代码自解密.doc
本文 PDF 下载地址:计算机病毒——代码自解密.pdf
留言与评论(共有 0 条评论) |