在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
来自:http://bbs.pediy.com/showthread.php?t=57671
{*****************************************************************
AddShell()源自于前一段时间有写的addsection()新增区段代码, 在增加区段代码的基础上,追加了 1.修改启动入口点位置 2.增加一段壳头xor $50的代码function AttachStart-function AttachEnd 这一段代码是先填充,再被修改成合适原EXE的壳头 3.修改原启动代码入口点所在区段的段属性可写并进行xor $50运算加密 不支持addshell()处理已经过addshell的exe *****************************************************************} unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Edit1: TEdit; Button2: TButton; Button3: TButton; procedure Button1Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1 : TForm1; implementation {$R *.dfm} function AttachStart: dword; stdcall; //我们定义的待填充数据 asm pushfd pushad mov eax,$12345678 //将会被自动计算并修改为加密初始地址 mov ebx,$1234 //将会被自动计算并修改为加密大小 mov ecx,0 @AA: xor byte ptr[eax],$50 inc eax inc ecx cmp ecx,ebx jbe @aa popad popfd push $12345678 //将会被自动计算并修改为原OEP ret end; function AttachEnd: dword; stdcall; begin end; {-------------------------增加区块并实现简易加壳--------------------------------} procedure AddShell(lFileName: string; lBackup: boolean); //打开exe文件,是否备份 var hFile : THandle; //文件句柄 ImageDosHeader : IMAGE_DOS_HEADER; //DOS部首 ImageNtHeaders : IMAGE_NT_HEADERS; //映象头 ImageSectionHeader: IMAGE_SECTION_HEADER; //块表 lPointerToRawData : dword; //指向文件中的偏移 lVirtualAddress : dword; //指向内存中的偏移 i : integer; //循环变量 BytesRead, ByteSWrite: Cardinal; //读写用参数 AttachSize : dword; //附加段大小 AttachData, ChangeData: integer; //附加段填充数据 OEP : integer; //使用过程中用到的EP lpBuffer : array[0..1024 * 400] of byte; {待加密数据存储缓冲区} nNumberOfBytesToRead, lpNumberOfBytesRead: dword; //加密时用到的一些数据 StartEN, SizeEN, StartCr: dword; //加密用的开始物理地址和大小 begin //定义附加段填充数据 AttachData := 0; //打开文件 hFile := CreateFile(PChar(lFileName), GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); //校验 if hFile = INVALID_HANDLE_VALUE then begin ShowMessage('打开文件失败'); exit; end; //确认备份 if lBackup then CopyFile(PChar(lFileName), PChar(lFileName + '.bak'), False); try //读取DOS部首到ImageDosHeader ReadFile(hFile, ImageDosHeader, SizeOf(ImageDosHeader), BytesRead, nil); //校验 if ImageDosHeader.e_magic <> IMAGE_DOS_SIGNATURE then begin ShowMessage('不是有效的PE文件!'); exit; end; //指向映象头 SetFilePointer(hFile, ImageDosHeader._lfanew, nil, FILE_BEGIN); //读取映向头到ImageNtHeaders ReadFile(hFile, ImageNtHeaders, SizeOf(ImageNtHeaders), BytesRead, nil); //校验 if ImageNtHeaders.Signature <> IMAGE_NT_SIGNATURE then begin ShowMessage('不是有效的PE文件'); exit; end; {********************************} {OEP=基址+原EP} OEP := ImageNtHeaders.OptionalHeader.ImageBase + ImageNtHeaders.OptionalHeader.AddressOfEntryPoint; {********************************} //计算加入块对齐后大小 AttachSize := ((integer(@AttachEnd) - integer(@AttachStart)) div ImageNtHeaders.OptionalHeader.FileAlignment + 1) * ImageNtHeaders.OptionalHeader.FileAlignment; //初始化文件中偏移和映象中偏移 lPointerToRawData := 0; lVirtualAddress := 0; for i := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do begin //读取块表中信息 ReadFile(hFile, ImageSectionHeader, SizeOf(ImageSectionHeader), BytesRead, nil); {********************************} {查找原EP所在区段(原EP所在区段),记录物理偏移(加密用初始地址),物理大小(加密用长度)} if LPCSTR(@ImageSectionHeader.Name[0]) = '.EN' then begin ShowMessage('已经过本addshell处理!'); exit; end; if ImageNtHeaders.OptionalHeader.AddressOfEntryPoint > ImageSectionHeader.VirtualAddress then begin StartEN := ImageSectionHeader.PointerToRawData; SizeEN := ImageSectionHeader.SizeOfRawData; StartCr := ImageNtHeaders.OptionalHeader.ImageBase + ImageSectionHeader.VirtualAddress; end; {********************************} //计算文件中偏移 if lPointerToRawData < ImageSectionHeader.PointerToRawData + ImageSectionHeader.SizeOfRawData then lPointerToRawData := ImageSectionHeader.PointerToRawData + ImageSectionHeader.SizeOfRawData; //计算映象中偏移 if lVirtualAddress < ImageSectionHeader.VirtualAddress + ImageSectionHeader.Misc.VirtualSize then lVirtualAddress := ImageSectionHeader.VirtualAddress + ImageSectionHeader.Misc.VirtualSize; end; {增加块,定义块各项属性} Move('.EN'#0, ImageSectionHeader.Name[0], 5); //设置初始属性 ImageSectionHeader.Misc.VirtualSize := AttachSize; ImageSectionHeader.VirtualAddress := lVirtualAddress; ImageSectionHeader.SizeOfRawData := AttachSize; ImageSectionHeader.PointerToRawData := lPointerToRawData; ImageSectionHeader.PointerToRelocations := 0; ImageSectionHeader.PointerToLinenumbers := 0; ImageSectionHeader.NumberOfRelocations := 0; //校正新节物理偏移(物理区块对齐) if ImageSectionHeader.VirtualAddress mod ImageNtHeaders.OptionalHeader.SectionAlignment > 0 then ImageSectionHeader.VirtualAddress := (ImageSectionHeader.VirtualAddress div ImageNtHeaders.OptionalHeader.SectionAlignment + 1) * ImageNtHeaders.OptionalHeader.SectionAlignment; //校正新节映象偏移(映象中区块对齐) if ImageSectionHeader.Misc.VirtualSize mod ImageNtHeaders.OptionalHeader.SectionAlignment > 0 then ImageSectionHeader.Misc.VirtualSize := (ImageSectionHeader.Misc.VirtualSize div ImageNtHeaders.OptionalHeader.SectionAlignment + 1) * ImageNtHeaders.OptionalHeader.SectionAlignment; //设置区块属性 ImageSectionHeader.Characteristics := $E00000E0; //保存区块信息 WriteFile(hFile, ImageSectionHeader, SizeOf(ImageSectionHeader), ByteSWrite, nil); //校正内存映象大小 ImageNtHeaders.OptionalHeader.SizeOfImage := ImageNtHeaders.OptionalHeader.SizeOfImage + ImageSectionHeader.Misc.VirtualSize; //更新OEP ImageNtHeaders.OptionalHeader.AddressOfEntryPoint := ImageSectionHeader.VirtualAddress; //校正块数目 Inc(ImageNtHeaders.FileHeader.NumberOfSections); //定位到映象头 SetFilePointer(hFile, ImageDosHeader._lfanew, nil, FILE_BEGIN); //保存校正过的映象头 WriteFile(hFile, ImageNtHeaders, SizeOf(ImageNtHeaders), ByteSWrite, nil); //定位到新节开始处 SetFilePointer(hFile, ImageSectionHeader.PointerToRawData, nil, FILE_BEGIN); //用00数据填充满新节 for i := 1 to AttachSize do begin WriteFile(hFile, PByte(@AttachData)^, 1, ByteSWrite, nil); end; {填充自定义数据} //指向新节开始处 SetFilePointer(hFile, ImageSectionHeader.PointerToRawData, nil, FILE_BEGIN); //填充我们定义的数据 WriteFile(hFile, PByte(@AttachStart)^, integer(@AttachEnd) - integer(@AttachStart), ByteSWrite, nil); {********************************} //修改所谓的外壳处大量数据 ChangeData := ImageSectionHeader.PointerToRawData + 3; SetFilePointer(hFile, ChangeData, nil, FILE_BEGIN); WriteFile(hFile, StartCr, 4, ByteSWrite, nil); //开始加密地址 ChangeData := ChangeData + 5; SetFilePointer(hFile, ChangeData, nil, FILE_BEGIN); WriteFile(hFile, SizeEN, 4, ByteSWrite, nil); //大小 ChangeData := ChangeData + 21; SetFilePointer(hFile, ChangeData, nil, FILE_BEGIN); WriteFile(hFile, OEP, 4, ByteSWrite, nil); //跳回OEP {********************************} //没有异常,显示增加区块成功! ShowMessage('增加区块成功!'); SetFilePointer(hFile, StartEN, nil, FILE_BEGIN); ReadFile(hFile, lpBuffer, SizeEN, BytesRead, nil); for i := 0 to SizeEN - 1 do begin byte(pointer(integer(@lpBuffer) + i)^) := byte(pointer(integer(@lpBuffer) + i)^) xor $50; end; SetFilePointer(hFile, StartEN, nil, FILE_BEGIN); WriteFile(hFile, lpBuffer, SizeEN, ByteSWrite, nil); //没有异常,显示变换成功! ShowMessage('变换数据成功!'); {********************************} SetFilePointer(hFile, (ImageDosHeader._lfanew + SizeOf(ImageNtHeaders)), nil, FILE_BEGIN); for i := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do begin //读取块表中信息 ReadFile(hFile, ImageSectionHeader, SizeOf(ImageSectionHeader), BytesRead, nil); if ImageSectionHeader.PointerToRawData = StartEN then begin ImageSectionHeader.Characteristics := $E00000E0; SetFilePointer(hFile, -SizeOf(ImageSectionHeader), nil, FILE_CURRENT); //保存区块信息 WriteFile(hFile, ImageSectionHeader, SizeOf(ImageSectionHeader), ByteSWrite, nil); Break; end; end; ShowMessage('修改区段属性成功!'); {********************************} finally {8.退出} //关闭文件 CloseHandle(hFile); end; end; {*************************Func end*********************************} procedure TForm1.Button1Click(Sender: TObject);//addshell begin AddShell(Edit1.text, true); end; procedure TForm1.Button3Click(Sender: TObject);//browser begin with TOpenDialog.Create(Self) do try Filter := '可执行文件 (*.exe)|*.exe'; if Execute then begin Edit1.text := FileName; end; finally Free; end; end; procedure TForm1.Button2Click(Sender: TObject);//exit begin close; end; end. |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论