zoukankan      html  css  js  c++  java
  • HookEngine源码

    unit uSection;

    interface

    uses
    Windows, Classes, SysUtils, uTypes, uCodeSize;

    function AddSection(FileName: string; Info: PRecInfo; SectionSize: Word): Boolean;

    var
    LOAD_ORION_NEW: array [0 .. 50] of Byte = (
    $68, // PUSH
    $1A, $5E, $75, $00, // main_exe.00755E1A Orion.dll
    $FF, $15, // CALL
    $7C, $62, $75, $00, // DWORD PTR DS:[75627C] LoadLibraryA 7
    $85, $C0, // TEST EAX,EAX
    $74, $00, // JE SHORT main_exe.0920200F
    $68, // PUSH
    $25, $5E, $75, $00, // main_exe.00755E25 Initialize
    $50, // PUSH EAX
    $FF, $15, // CALL
    $78, $64, $75, $00, // DWORD PTR DS:[756278] GetProcessAddress 23
    $85, $C0, // TEST EAX,EAX
    $74, $10, // JE SHORT main_exe.0920202F
    $FF, $D0, // CALL EAX Call Initialize
    $6A, $10, // PUSH 10
    $68, // PUSH
    $FC, $5D, $75, $00, // main_exe.00755DFC Caption 36
    $68, // PUSH
    $C0, $5D, $75, $00, // main_exe.00755DC0 Content 41
    $FF, $15, // CALL
    $50, $13, $75, $00); // DWORD PTR DS:[756350] MessageBoxA

    LOAD_ORION: array [0 ..59] of Byte = (
    $68, // PUSH
    $00, $34, $20, $09, // main_exe.00755E1A Orion.dll
    $FF, $15, // CALL
    $08, $12, $8D, $00, // DWORD PTR DS:[75627C] LoadLibraryA 7
    $85, $C0, // TEST EAX,EAX
    $74, $17, // JE 17 Bytes 14
    $68, // PUSH
    $10, $34, $20, $09, // main_exe.00755E25 Initialize
    $50, // PUSH EAX
    $FF, $15, // CALL
    $04, $12, $8D, $00, // DWORD PTR DS:[756278] GetProcessAddress 23
    $85, $C0, // TEST EAX,EAX
    $74, $07, // JE 7 bytes
    $FF, $D0, // CALL EAX
    $E9, // JMP
    $C6, $EB, $69, $F7, // OEP OFFSET 34
    $6A, $10, // PUSH 10
    $68, // PUSH
    $40, $34, $20, $09, // Header offset 42
    $68, // PUSH
    $20, $34, $20, $09, // Content offset
    $6A, $00, // PUSH 0
    $FF, $15, // CALL
    $50, $13, $75, $00, // MESSAGEBOXA 55
    $C3,
    $90
    );

    implementation

    {$REGION 'Functions'}

    function GetFieldOffset(const Struc; const Field): Cardinal; stdcall;
    begin
    Result := Cardinal(@Field) - Cardinal(@Struc);
    end;

    function GetImageFirstSection(NtHeader: PImageNtHeaders): PImageSectionHeader; stdcall;
    begin
    Result := PImageSectionHeader(Cardinal(NtHeader) +
    GetFieldOffset(NtHeader^, NtHeader^.OptionalHeader) +
    NtHeader^.FileHeader.SizeOfOptionalHeader);
    end;

    function PEAlign(Num, AlignTo: DWORD):DWORD;
    begin
    while (Num mod AlignTo) <> 0 do
    inc(Num);
    Result := Num;
    end;

    function Align(dwValue:DWORD; dwAlign:DWORD):DWORD;
    begin
    if dwAlign <> 0 then
    begin
    if dwValue mod dwAlign <> 0 then
    begin
    Result := (dwValue + dwAlign) - (dwValue mod dwAlign);
    Exit;
    end;
    end;
    Result := dwValue;
    end;

    function LastSectionRaw(Sections: array of TImageSectionHeader):DWORD;
    var
    i: integer;
    Ret: DWORD;
    begin
    Ret := 0;
    for i := Low(Sections) to High(Sections) do
    begin
    if Sections[i].SizeOfRawData + Sections[i].PointerToRawData > Ret then
    Ret := Sections[i].SizeOfRawData + Sections[i].PointerToRawData;
    end;
    Result := Ret;
    end;

    function LastSectionVirtual(Sections: array of TImageSectionHeader):DWORD;
    var
    i: integer;
    Ret: DWORD;
    begin
    Ret := 0;
    for i := Low(Sections) to High(Sections) do
    begin
    if Sections[i].Misc.VirtualSize + Sections[i].VirtualAddress > Ret then
    Ret := Sections[i].Misc.VirtualSize + Sections[i].VirtualAddress;
    end;
    Result := Ret;
    end;

    function GetSection(NTHeader: PImageNtHeaders; Section: word):PImageSectionHeader;
    var
    Adr: DWORD;
    begin
    Adr := Integer(NTHeader)+SizeOf(IMAGE_NT_HEADERS)+(Section-1)*SizeOf(IMAGE_SECTION_HEADER);
    Result := Ptr(Adr);
    end;

    function RAWToSection(Head: PImageNtHeaders; RAW: DWORD):PImageSectionHeader;
    var i: integer;
    Section: PImageSectionHeader;
    begin
    Section := nil;
    for i:=1 to Head.FileHeader.NumberOfSections do
    begin
    Section := GetSection(Head, i);
    if Section.PointerToRawData>RAW then
    begin
    result := GetSection(Head, i-1);
    exit;
    end;
    end;
    Result := Section; // most probably the last section...
    end;

    function RVAToSection(Head: PImageNtHeaders; RVA: DWORD):PImageSectionHeader;
    // this is because ImageRVAToSection exported from
    // imagehlp.dll sucks. Sucks a lot. And doesn't work...
    var i: integer;
    Section: PImageSectionHeader;
    begin
    Section:=nil;
    for i:=1 to Head.FileHeader.NumberOfSections do
    begin
    Section:=GetSection(Head, i);
    if Section.VirtualAddress>RVA then
    begin
    result:=GetSection(Head, i-1);
    exit;
    end;
    end;
    Result:=Section; // most probably the last section...
    end;

    function RVAToRAW(Head: PImageNtHeaders; RVA: DWORD):DWORD;
    var s: PImageSectionHeader;
    begin
    s:= RVAToSection(Head, RVA);
    Result:=RVA - s.VirtualAddress + s.PointerToRawData;
    end;

    function RAWToRVA(Head: PImageNtHeaders; RAW: DWORD):DWORD;
    var s: PImageSectionHeader;
    begin
    s:=RAWToSection(Head, RAW);
    Result:=RAW-s.PointerToRawData+s.VirtualAddress;
    end;

    function GetImageNTHeaders(Address: DWORD):PImageNtHeaders;
    var NewHeader: PWord;
    begin
    NewHeader:=Ptr(Address+$3C); // Position of PE header
    result:=Ptr(NewHeader^+Address); // Map it to IMAGE_NT_HEADERS
    if PDWORD(Result)^<>IMAGE_NT_SIGNATURE then
    result:=nil;
    end;

    function WriteBuffer(Buffer,Data: TBytes): TBytes;
    begin
    SetLength(Result, Length(Buffer) + 5);
    Move(Buffer, Result, Length(Buffer));
    Move(Result[Length(Buffer)], Data[0], 5);
    end;

    procedure Obfuscate(Head: PImageSectionHeader);
    begin
    Head.PointerToRawData := Head.PointerToRawData + $100;
    end;

    {$ENDREGION}

    function AddSection(FileName: string; Info: PRecInfo; SectionSize: Word): Boolean;
    var
    Fs: TFileStream;
    ImgDosHdr: TImageDosHeader;
    NtImgDosHdr: TImageNtHeaders;
    ImportDesc: PImageImportDescriptor;
    Sections: TArray;
    SectionsCount: Word;
    Buffer: TBytes;
    i: Integer;
    x: Cardinal;
    PointerIAT: DWORD;
    FTunk: Cardinal;
    FLoadLibrary, FMessageBox, FGetProcAddress: Cardinal;
    OEP: Cardinal;

    {$REGION 'More Functions T_T'}

    function GetSectionIndex(dwAddr: DWORD): DWORD;
    var
    i: Integer;
    begin
    for i := 0 to NtImgDosHdr.FileHeader.NumberOfSections -1 do
    if (dwAddr >= Sections[i].VirtualAddress) and (dwAddr < Sections[i].VirtualAddress + Sections[i].Misc.VirtualSize) then
    begin
    Result := i;
    break;
    end;
    end;

    function RVAToOffset(dwRVA: DWORD): DWORD;
    var
    sIndex: DWORD;
    begin
    sIndex := GetSectionIndex(dwRVA);
    Result := Sections[sIndex].PointerToRAWData - Sections[sIndex].VirtualAddress + dwRVA;
    end;

    function RVA2RAW(Addr: DWORD; SectionHeaders: TArray): DWORD;
    var
    i: Integer;
    begin
    Result := 0;
    for i:=0 to length(SectionHeaders)-1 do
    if (SectionHeaders[i].VirtualAddress <= Addr) and (SectionHeaders[i].VirtualAddress+SectionHeaders[i].Misc.VirtualSize > Addr) then
    begin
    Result := Addr - SectionHeaders[i].VirtualAddress + SectionHeaders[i].PointerToRawData;
    break;
    end;
    end;

    function RvaOfNewSection(Rva,LastRva,SizeLast: Word): Dword;
    begin
    Result := (Rva - LastRva) + SizeLast;
    end;

    procedure ASMJmpOEP();
    asm
    mov eax, 0FFFFFFFFh
    jmp eax
    end;

    {$ENDREGION}

    begin
    Result := False;

    try
    Fs := TFileStream.Create(FileName,fmOpenRead);
    try
    SetLength(Buffer, Fs.Size);
    Fs.ReadBuffer(Buffer[0],Length(Buffer));

    Fs.Position := 0;
    if Fs.Read(ImgDosHdr, 64) <> 64 then
    Exit;

    Fs.Position := ImgDosHdr._lfanew;
    if Fs.Read(NtImgDosHdr, 248) <> 248 then
    Exit;

    finally
    Fs.Free;
    end;


    if ImgDosHdr.e_magic = IMAGE_DOS_SIGNATURE then
    if NtImgDosHdr.Signature = IMAGE_NT_SIGNATURE then
    begin

    SectionsCount := NtImgDosHdr.FileHeader.NumberOfSections;
    SetLength(Sections, SectionsCount);

    x := ImgDosHdr._lfanew + 24 + NtImgDosHdr.FileHeader.SizeOfOptionalHeader;

    for i := low(Sections) to high(Sections) do
    begin
    Move(Buffer[x], Sections[i] ,40);
    Inc(x, 40);
    end;

    if NtImgDosHdr.OptionalHeader.SizeOfHeaders >= (x + 40) then
    begin
    Inc(NtImgDosHdr.FileHeader.NumberOfSections, 1);
    SetLength(Sections, NtImgDosHdr.FileHeader.NumberOfSections);

    with Sections[NtImgDosHdr.FileHeader.NumberOfSections] do
    begin
    FillChar(Name, SizeOf(Name), #0);
    Name[0] := Ord('.');
    Name[1] := Ord('O');
    Name[2] := Ord('r');
    Name[3] := Ord('i');
    Name[4] := Ord('o');
    Name[5] := Ord('n');
    Characteristics := $E0000060;
    PointerToRawData := Align(LastSectionRaw(Sections), NtImgDosHdr.OptionalHeader.FileAlignment);
    SizeOfRawData := Align(SectionSize, NtImgDosHdr.OptionalHeader.FileAlignment);
    VirtualAddress := Align(LastSectionVirtual(Sections), NtImgDosHdr.OptionalHeader.SectionAlignment);
    Misc.VirtualSize := Align(SectionSize, NtImgDosHdr.OptionalHeader.SectionAlignment);
    end;
    end;

    ImportDesc := @Buffer[RVAToOffset(NtImgDosHdr.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)];
    if ASSIGNED(ImportDesc) then
    begin
    with NtImgDosHdr.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] do
    begin
    repeat
    if Size > 0 then
    begin
    PointerIAT := RVA2RAW(ImportDesc.FirstThunk, Sections);
    FTunk := importDesc.FirstThunk ;
    repeat

    if Pos('LoadLibraryA', PAnsiChar(@Buffer[RVA2RAW(pdword(@Buffer[PointerIAT])^ +2, Sections)])) > 0 then
    FLoadLibrary := FTunk + NtImgDosHdr.OptionalHeader.ImageBase;
    if Pos('GetProcAddress', PAnsiChar(@Buffer[RVA2RAW(pdword(@Buffer[PointerIAT])^ +2, Sections)])) > 0 then
    FGetProcAddress := FTunk + NtImgDosHdr.OptionalHeader.ImageBase;
    if Pos('MessageBoxA', PAnsiChar(@Buffer[RVA2RAW(pdword(@Buffer[PointerIAT])^ +2, Sections)])) > 0 then
    FMessageBox := FTunk + NtImgDosHdr.OptionalHeader.ImageBase;

    inc(PointerIAT, 4);
    Inc(FTunk,4);
    until (PDword(@Buffer[PointerIAT])^ = 0);
    end;
    ImportDesc := ptr(dword(ImportDesc) + SizeOf(TImageImportDescriptor));
    until (ImportDesc.OriginalFirstThunk = 0) and (ImportDesc.Name = 0);
    end;
    end;

    NtImgDosHdr.OptionalHeader.DataDirectory[11].VirtualAddress := 0;
    NtImgDosHdr.OptionalHeader.DataDirectory[11].Size := 0;
    Inc(NtImgDosHdr.OptionalHeader.SizeOfImage, Sections[NtImgDosHdr.FileHeader.NumberOfSections].Misc.VirtualSize);

    OEP := NtImgDosHdr.OptionalHeader.AddressOfEntryPoint + NtImgDosHdr.OptionalHeader.ImageBase;
    // Mainam OEP -> uz jauno EP:)
    NtImgDosHdr.OptionalHeader.AddressOfEntryPoint := Sections[NtImgDosHdr.FileHeader.NumberOfSections].VirtualAddress;

    Move(NtImgDosHdr, Buffer[ImgDosHdr._lfanew], 248);
    Move(Sections[NtImgDosHdr.FileHeader.NumberOfSections], Buffer[x], 40);

    SectionSize := Align(SectionSize, NtImgDosHdr.OptionalHeader.FileAlignment);
    SetLength(Buffer, Length(Buffer) + SectionSize);

    // Mainam IAT pirms rakstam

    Move(Info^.DLL[0],Info^.WriteBytes[Length(LOAD_ORION) + 1], Length(Info^.DLL));
    Move(Info^.Hdr[0],Info^.WriteBytes[Length(Info^.DLL) + Length(LOAD_ORION) + 2], Length(Info^.Hdr));
    Move(Info^.Content[0],Info^.WriteBytes[Length(Info^.DLL) + Length(Info^.Hdr) + Length(LOAD_ORION) + 3], Length(Info^.Content));

    if Info^.CallApi then
    begin
    Move(Info^.API[0],Info^.WriteBytes[Length(Info^.DLL) + Length(Info^.Hdr) + Length(Info^.Content) + Length(LOAD_ORION) + 4], Length(Info^.API)); // Add API name
    PDWORD(@LOAD_ORION[1])^ := (NtImgDosHdr.OptionalHeader.AddressOfEntryPoint + NtImgDosHdr.OptionalHeader.ImageBase) + (Length(LOAD_ORION) + 1); //DLL Name
    PDWORD(@LOAD_ORION[16])^ := (NtImgDosHdr.OptionalHeader.AddressOfEntryPoint + NtImgDosHdr.OptionalHeader.ImageBase) + (Length(Info^.DLL) + Length(LOAD_ORION) + Length(Info^.Hdr) + Length(Info^.Content) + 4); //API Name position
    PDWORD(@LOAD_ORION[41])^ := (NtImgDosHdr.OptionalHeader.AddressOfEntryPoint + NtImgDosHdr.OptionalHeader.ImageBase) + (Length(Info^.DLL) + Length(LOAD_ORION) + 2); //Message header
    PDWORD(@LOAD_ORION[46])^ := (NtImgDosHdr.OptionalHeader.AddressOfEntryPoint + NtImgDosHdr.OptionalHeader.ImageBase) + (Length(Info^.DLL) + Length(LOAD_ORION) + Length(Info^.Hdr) + 3); //Message content
    PDWORD(@LOAD_ORION[23])^ := FGetProcAddress; // Call GetProcessAddress
    LOAD_ORION[30] := $07; // Jmp 7 bytes to MessageBox
    PDWORD(@LOAD_ORION[54])^ := FMessageBox; // Call MessageBoxA
    PDWORD(@LOAD_ORION[7])^ := FLoadLibrary; // Call loadlibrary
    LOAD_ORION[14] := $17; // Jmp 19 bytes to MessageBox
    PDWORD(@LOAD_ORION[34])^ := OEP - (NtImgDosHdr.OptionalHeader.AddressOfEntryPoint + NtImgDosHdr.OptionalHeader.ImageBase + 38);
    end
    else
    begin
    PDWORD(@LOAD_ORION[1])^ := (NtImgDosHdr.OptionalHeader.AddressOfEntryPoint + NtImgDosHdr.OptionalHeader.ImageBase) - (Length(Info^.DLL) + Length(Info^.Hdr) + Length(Info^.Content) + 3); //DLL Name
    PDWORD(@LOAD_ORION[7])^ := FLoadLibrary; // Call loadlibrary
    Move(LOAD_ORION[33],LOAD_ORION[15],25);
    FillChar(LOAD_ORION[39], 21, #0);
    LOAD_ORION[14] := $05;

    PDWORD(@LOAD_ORION[1])^ := (NtImgDosHdr.OptionalHeader.AddressOfEntryPoint + NtImgDosHdr.OptionalHeader.ImageBase) + (Length(LOAD_ORION) + 1); //DLL Name
    PDWORD(@LOAD_ORION[23])^ := (NtImgDosHdr.OptionalHeader.AddressOfEntryPoint + NtImgDosHdr.OptionalHeader.ImageBase) + (Length(Info^.DLL) + Length(LOAD_ORION) + 2); //Message header
    PDWORD(@LOAD_ORION[28])^ := (NtImgDosHdr.OptionalHeader.AddressOfEntryPoint + NtImgDosHdr.OptionalHeader.ImageBase) + (Length(Info^.DLL) + Length(LOAD_ORION) + Length(Info^.Hdr) + 3); //Message content
    PDWORD(@LOAD_ORION[36])^ := FMessageBox; // Call MessageBoxA
    PDWORD(@LOAD_ORION[16])^ := OEP - (NtImgDosHdr.OptionalHeader.AddressOfEntryPoint + NtImgDosHdr.OptionalHeader.ImageBase + 20);
    end;


    Move(LOAD_ORION,Info.WriteBytes[0], Length(LOAD_ORION));
    Move(Info.WriteBytes[0], Buffer[Length(Buffer) - SectionSize], Length(Info.WriteBytes));
    end;

    Fs := TFileStream.Create(Filename+'_HOOKED_DLL.exe',fmCreate or fmShareExclusive);
    try
    Result := Fs.Write(Buffer[0],Length(Buffer)) = Length(Buffer);
    finally
    Fs.Free
    end;
    except
    on E: Exception do
    MessageBox(0, PWideChar(E.Message) , '', MB_ICONERROR or MB_OK);
    end;
    end;

    end.

  • 相关阅读:
    nginx升级步骤
    对一些信息进行正则校验
    对list对象进行排序
    文件上传实现ajax假异步
    解决springmvc+fastjson返回页面出现乱码问题
    php opcode缓存
    node.js 抓取
    mysql 好文章
    rabbitmq 安装
    配置安装nginx
  • 原文地址:https://www.cnblogs.com/plug/p/8665566.html
Copyright © 2011-2022 走看看