📄 sunrise_pe.pas
字号:
dw_eax,
dw_ebx,
dw_ecx,
dw_edx,
dw_esi,
dw_edi,
dw_esp,
dw_ebp,
dw_efl,
dw_eip,
dw_pcode,
dw_vmcode,
dw_vmlen,
dw_trlen,
dw_tmp:cardinal;
chs_cmd:pansichar;
label vm_start;
begin
//执行核心
asm
pushad
pushfd
mov dw_eax,eax
mov dw_ebx,ebx
mov dw_ecx,ecx
mov dw_edx,edx
mov dw_esi,esi
mov dw_edi,edi
pop dw_efl
push dw_efl
popfd
popad
end;
dw_esp := dw_resp;
dw_ebp := dw_rebp;
dw_eip := dw_reip + dw_imagebase;
dw_pcode := p_vmcode;
vm_start:
dw_vmlen := 0;
dw_trlen := 0;
chs_cmd := pointer(dw_pcode);
//-------------------------------------------------------------------------
case chs_cmd[0] of
Char(VM_T_CHAR0):
begin
dw_vmcode := shell_vmachine_getvalue(dw_pcode);
case chs_cmd[1] of
Char(VM_T_GROUP_0):
begin
case chs_cmd[2] of
Char(VM_T_GROUP_0_0):
begin
case chs_cmd[3] of
Char(VM_C_PUEBP): //push ebp
begin
dw_esp := dw_esp-BIT32_CMDLEN;
shell_vmachine_Setvalue(dw_ebp,dw_esp);
dw_vmlen := sizeof(VM_T_PUEBP);
dw_trlen := VM_L_PUEBP;
end;
Char(VM_C_S_PUSH): //push 70
begin
dw_tmp :=shell_vmachine_getvalue(dw_pcode+sizeof(VM_T_S_PUSH));
dw_esp := dw_esp-BIT32_CMDLEN;
shell_vmachine_Setvalue(dw_tmp,dw_esp);
dw_vmlen := sizeof(VM_T_S_PUSH)+sizeof(cardinal);
dw_trlen := VM_L_S_PUSH;
end;
Char(VM_C_L_PUSH): //push xxxxxxxx
begin
dw_tmp :=shell_vmachine_getvalue(dw_pcode+sizeof(VM_T_L_PUSH));
dw_esp := dw_esp-BIT32_CMDLEN;
shell_vmachine_Setvalue(dw_tmp,dw_esp);
dw_vmlen := sizeof(VM_T_L_PUSH)+sizeof(cardinal);
dw_trlen := VM_L_L_PUSH;
end;
end;
end;
Char(VM_T_GROUP_0_1):
begin
case chs_cmd[3] of
char(VM_C_MOEBPESP): //mov ebp,esp
begin
dw_ebp := dw_esp;
dw_vmlen := sizeof(VM_T_MOEBPESP);
dw_trlen := VM_L_MOEBPESP;
end;
Char(VM_C_L_MOVEAX): //mov eax,xxxxxxxx
begin
dw_tmp :=shell_vmachine_getvalue(dw_pcode+sizeof(VM_T_L_MOVEAX));
dw_eax := dw_tmp;
dw_vmlen := sizeof(VM_T_L_MOVEAX)+sizeof(cardinal);
dw_trlen := VM_L_L_MOVEAX;
end;
Char(VM_C_M_MOVEAX): //mov eax,dword ptr [xxxxxxxx]
begin
dw_tmp :=shell_vmachine_getvalue(dw_pcode+sizeof(VM_T_M_MOVEAX));
asm
push eax
mov eax,dw_tmp
mov eax,dword ptr [eax]
mov dw_tmp,eax
pop eax
end;
dw_eax := dw_tmp;
dw_vmlen := sizeof(VM_T_M_MOVEAX)+sizeof(cardinal);
dw_trlen := VM_L_M_MOVEAX;
end;
Char(VM_C_M_MOVEBX): //mov ebx,dword ptr [xxxxxxxx]
begin
dw_tmp :=shell_vmachine_getvalue(dw_pcode+sizeof(VM_T_M_MOVEBX));
asm
push eax
mov eax,dw_tmp
mov eax,dword ptr [eax]
mov dw_tmp,eax
pop eax
end;
dw_eBx := dw_tmp;
dw_vmlen := sizeof(VM_T_M_MOVEBX)+sizeof(cardinal);
dw_trlen := VM_L_M_MOVEBX;
end;
Char(VM_C_M_MOVECX): //mov ecx,dword ptr [xxxxxxxx]
begin
dw_tmp :=shell_vmachine_getvalue(dw_pcode+sizeof(VM_T_M_MOVECX));
asm
push eax
mov eax,dw_tmp
mov eax,dword ptr [eax]
mov dw_tmp,eax
pop eax
end;
dw_ecx := dw_tmp;
dw_vmlen := sizeof(VM_T_M_MOVECX)+sizeof(cardinal);
dw_trlen := VM_L_M_MOVECX;
end;
Char(VM_C_M_MOVEDX)://mov edx,dword ptr [xxxxxxxx]
begin
dw_tmp :=shell_vmachine_getvalue(dw_pcode+sizeof(VM_T_M_MOVEDX));
asm
push eax
mov eax,dw_tmp
mov eax,dword ptr [eax]
mov dw_tmp,eax
pop eax
end;
dw_edx := dw_tmp;
dw_vmlen := sizeof(VM_T_M_MOVEDX)+sizeof(cardinal);
dw_trlen := VM_L_M_MOVEDX;
end;
Char(VM_C_MOEAX_M_EAX): //mov eax,dword ptr [eax]
begin
dw_tmp :=dw_eax;
asm
push eax
mov eax,dw_tmp
mov eax,dword ptr [eax]
mov dw_tmp,eax
pop eax
end;
dw_eax := dw_tmp;
dw_vmlen := sizeof(VM_T_MOEAX_M_EAX);
dw_trlen := VM_L_MOEAX_M_EAX;
end;
Char(VM_C_L_MOVEBX): //mov ebx,xxxxxxxx
begin
dw_tmp :=shell_vmachine_getvalue(dw_pcode+sizeof(VM_T_L_MOVEBX));
dw_ebx := dw_tmp;
dw_vmlen := sizeof(VM_T_L_MOVEBX)+sizeof(cardinal);
dw_trlen := VM_L_L_MOVEBX;
end;
Char(VM_C_L_MOVECX): //mov ecx,xxxxxxxx
begin
dw_tmp :=shell_vmachine_getvalue(dw_pcode+sizeof(VM_T_L_MOVECX));
dw_ecx := dw_tmp;
dw_vmlen := sizeof(VM_T_L_MOVECX)+sizeof(cardinal);
dw_trlen := VM_L_L_MOVECX;
end;
Char(VM_C_L_MOVEDX): //mov edx,xxxxxxxx
begin
dw_tmp :=shell_vmachine_getvalue(dw_pcode+sizeof(VM_T_L_MOVEDX));
dw_edx := dw_tmp;
dw_vmlen := sizeof(VM_T_L_MOVEDX)+sizeof(cardinal);
dw_trlen := VM_L_L_MOVEDX;
end;
end;
end;
Char(VM_T_GROUP_0_2):
case chs_cmd[3] of //add esp,xx
Char(VM_C_S_ADDESP):
begin
dw_tmp :=shell_vmachine_getvalue(dw_pcode+sizeof(VM_T_S_ADDESP));
if dw_tmp > 128 then
dw_esp := dw_esp -(256-dw_tmp)
else
dw_esp := dw_esp + dw_tmp;
dw_vmlen := sizeof(VM_T_S_ADDESP)+sizeof(integer);
dw_trlen := VM_L_S_ADDESP;
end;
end;
Char(VM_T_GROUP_0_3):
begin
case chs_cmd[3] of
Char(VM_C_L_CALL): //call xxxxxxxx
begin
dw_tmp := shell_vmachine_getvalue(dw_pcode+sizeof(VM_T_L_CALL));
dw_tmp := dw_tmp+dw_eip+5;
dw_esp := dw_esp-BIT32_CMDLEN;
shell_vmachine_Setvalue(dw_tmp,dw_esp);//返回地址
dw_esp := dw_esp-BIT32_CMDLEN;
shell_vmachine_Setvalue(dw_tmp,dw_esp);
asm
pushad
pushfd
push ebp
call Shell_vmachine_ebp
push esp
call Shell_vmachine_esp
push dw_esp
jmp @return
@goon:
mov eax,dw_esp
add eax,4
pop dword ptr [eax]
mov eax,dw_eax
mov ebx,dw_ebx
mov ecx,dw_ecx
mov edx,dw_edx
mov esi,dw_esi
mov edi,dw_edi
mov ebp,dw_ebp
pop esp
ret
@return:
call @l_next
//处理返回
mov dw_eax,eax
mov dw_ebx,ebx
mov dw_ecx,ecx
mov dw_edx,edx
mov dw_esi,esi
mov dw_edi,edi
mov dw_ebp,ebp
push esp
call Shell_vmachine_vesp
push 0
call Shell_vmachine_ebp
mov ebp,eax
push 0
call Shell_vmachine_esp
mov esp,eax
push 0
call shell_vmachine_vesp
mov dw_esp,eax
popfd
popad
jmp @final
@l_next:
jmp @goon
@final:
end;
dw_vmlen := sizeof(VM_T_L_CALL)+sizeof(cardinal);
dw_trlen := VM_L_L_CALL;
end;
end;
end;
end;
end;
end;
end;
else
dw_esp := dw_esp-BIT32_CMDLEN;
shell_vmachine_Setvalue(dw_eip,dw_esp);
asm
mov eax,dw_eax
mov ebx,dw_ebx
mov ecx,dw_ecx
mov edx,dw_edx
mov esi,dw_esi
mov edi,dw_edi
push dw_efl
popfd
push dw_esp
mov ebp,dw_ebp
pop esp
ret
end;
end;
//-------------------------------------------------------------------------
dw_pcode := dw_pcode+dw_vmlen;
dw_eip := dw_eip + dw_trlen;
goto vm_start;
end;
function CodeStart_shell_vmachine_endloader():DWORD;
asm
call @CodeStart
@CodeStart:
pop eax
add eax,5
end;
procedure shell_vmachine_endloader();
begin
end;
procedure Shell_vmachine_loader();
asm
push 0
call Shell_vmachine_esp
push eax
pop eax
popfd
popad
pushad
pushfd
mov esp,dword ptr [esp-4]
jmp shell_vmachine_RunCode
end;
function shell_vmachine_Run(p_vmcode,dw_rebp,dw_resp,
dw_imagebase,dw_reip:cardinal):cardinal;stdcall;
asm
pushad
pushfd
push 0
call Shell_vmachine_esp
mov ebx,eax
call CodeStart_shell_vmachine_endloader
mov dword ptr [ebx],eax
mov eax,ebx
mov ebx,p_vmcode
mov dword ptr [eax+4],ebx
mov ebx,dw_rebp
mov dword ptr [eax+8],ebx
mov ebx,dw_resp
mov dword ptr [eax+12],ebx
mov ebx,dw_imagebase
mov dword ptr [eax+16],ebx
mov ebx,dw_reip
mov dword ptr [eax+20],ebx
jmp Shell_vmachine_loader
end;
function GenResOneDirAndEntry(var ResDirHeader:cardinal;var treeadr:cardinal;resentry:cardinal;p_VirtualAlloc:cardinal):cardinal;stdcall;
var
my_res_dir:Tmyresdir;
my_res_dir1:TMyresdir;
pe_res_dir:TIMAGERESDIRECTORY;
pe_res_entry:TIMAGERESDIRECTORYENTRY;
pe_res_data:TIMAGERESDIRECTORYENTRY;
i:cardinal;
bakadr:cardinal;
entryadr:cardinal;
begin
//资源部分比较复杂,所以写些注释
//读取自定义资源头
packer_movmem(resDirHeader,@my_res_dir,sizeof(my_res_dir));
ResDirHeader := ResDirHeader + sizeof(my_res_dir);
//构建标准的PE资源头
pe_res_dir.NumberOfIdEntries := my_res_dir.Numberofid;
pe_res_dir.NumberOfNamedEntries := my_res_dir.Numberofdir - my_res_dir.Numberofid;
//把标准PE资源头写入申请好的内存
packer_movmem(cardinal(@pe_res_dir),pointer(treeadr),sizeof(pe_res_dir));
treeadr := treeadr+sizeof(pe_res_dir);
//计算下一个资源目录开始的地址
bakadr := treeadr;
entryadr := bakadr;
treeadr := treeadr + (my_res_dir.Numberofdir * sizeof(pe_res_entry));
//循环建立data_entry以及子目录
for I := 0 to my_res_dir.Numberofdir - 1 do
begin
//计算地址
//读取自定义头并决定如何建立data_entry
packer_movmem(resDirHeader,@my_res_dir1,sizeof(my_res_dir1));
ResDirHeader := ResDirHeader + sizeof(my_res_dir1);
//构造entry里面的name
if my_res_dir1.isstringname = ENCRYPT_TRUE then
pe_res_entry.Name := $80000000 + ResDirHeader - 66 - resentry
else
pe_res_entry.Name := my_res_dir1.ID;
if my_res_dir1.NoRes = ENCRYPT_TRUE then
begin //还有子目录
pe_res_entry.ID := $80000000 + ResDirHeader - resentry;
packer_movmem(cardinal(@pe_res_entry),pointer(entryadr),sizeof(
pe_res_entry));
entryadr := entryadr + sizeof(pe_res_entry);
GenResOneDirAndEntry(resdirheader,treeadr,resentry,p_virtualalloc);
end
else
begin
pe_res_entry.ID := $80000000 + ResDirHeader - resentry;
packer_movmem(cardinal(@pe_res_entry),pointer(entryadr),sizeof(
pe_res_entry));
entryadr := entryadr + sizeof(pe_res_entry);
resdirheader := resdirheader+my_res_dir1.ressize;
end;
end;
end;
function GenResTree(ResData:cardinal;p_VirtualAlloc:cardinal):cardinal;stdcall;
var
asm_VirtualAlloc : function (lpvAddress: Pointer; dwSize,flAllocationType,
flProtect: DWORD): Pointer; stdcall;
treeadr :cardinal;
begin
asm_VirtualAlloc := pointer(p_VirtualAlloc);
treeadr := cardinal(asm_VirtualAlloc(nil,$1000,MEM_COMMIT,
PAGE_READWRITE));
GenResOneDirAndEntry(cardinal(resData),treeadr,treeadr,p_VirtualAlloc);
end;
function CodeStart_vm_mini():cardinal;
asm
call @CodeStart
@CodeStart:
pop eax
add eax,5
end;
function CodeEnd_vm_mini():cardinal;
asm
Call @CodeEnd
@CodeEnd:
pop eax
sub eax,5
end;
function CodeEnd_packer_main():DWORD;
asm
Call @CodeEnd
@CodeEnd:
pop eax
sub eax,5
end;
procedure asmfunctions();
begin
GetImageBase();
Packcode(0);
Codes
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -