⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sunrise_pe.pas

📁 一款压缩壳PE123的DELPHI源码 学习写壳的很好的参考
💻 PAS
📖 第 1 页 / 共 5 页
字号:
  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 + -