delphi如何在win7中远程注入代码

一. delphi远程注入Dll文件

  1. 首先,您必须找到已经在内存中运行的应用程序(EXE)的PID。以下函数将通过名称获得PID
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    function PIDbyName(ProcessName: PWideChar): DWORD;
    var
    ProcessSnap: Int64;
    ProcessEntry32: TProcessEntry32;
    begin
    Result := 0;
    ProcessSnap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if ProcessSnap <> INVALID_HANDLE_VALUE then
    begin
    ProcessEntry32.dwSize := SizeOf(TPROCESSENTRY32);
    if Process32First(ProcessSnap, ProcessEntry32) then
    repeat
    if lstrcmpi(ProcessEntry32.szExeFile, ProcessName) = 0 then
    begin
    Result := ProcessEntry32.th32ProcessID;
    CloseHandle(ProcessSnap);
    exit;
    end;
    until not Process32Next(ProcessSnap, ProcessEntry32);
    Result := 0;
    CloseHandle(ProcessSnap);
    end;
    end;
  2. 这是32/64位应用程序的DLL注入函数 Source是DLL,Target是EXE
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    function InjectDLL(Source, Target : PWideChar) : boolean;
    var
    dwThreadID: Cardinal;
    hProc, hThread: THandle;
    BytesToWrite, BytesWritten: SIZE_T;
    pRemoteBuffer, pLoadLibrary: Pointer;
    begin
    hProc := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_QUERY_INFORMATION or PROCESS_VM_OPERATION or PROCESS_VM_WRITE or PROCESS_VM_READ, False, PIDbyName(Target));
    if hProc = 0 then exit(false);
    try
    BytesToWrite := SizeOf(WideChar) * (Length(Source) + 1);
    pRemoteBuffer := VirtualAllocEx(hProc, nil, BytesToWrite, MEM_COMMIT,PAGE_READWRITE);
    if pRemoteBuffer = nil then exit(false);
    try
    if not WriteProcessMemory(hProc, pRemoteBuffer, Source, BytesToWrite, BytesWritten) then exit(false);
    pLoadLibrary := GetProcAddress(GetModuleHandle('kernel32.dll'), 'LoadLibraryW');
    hThread := CreateRemoteThread(hProc, nil, 0, pLoadLibrary, pRemoteBuffer, 0, dwThreadID);
    try
    WaitForSingleObject(hThread, INFINITE);
    finally
    Result := true;
    CloseHandle(hThread);
    end;
    finally
    VirtualFreeEx(hProc, pRemoteBuffer, 0, MEM_RELEASE);
    end;
    finally
    CloseHandle(hProc);
    end;
    end;
  3. 简单的DLL
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    library testDLL;

    uses
    System.SysUtils,
    System.Classes,
    Winapi.Windows;

    {$R *.res}

    procedure DLLEntryPoint(dwReason: DWord);
    var
    DLLHandle : DWORD;
    begin
    case dwReason of
    DLL_PROCESS_ATTACH:
    MessageBox(DLLHandle, 'Process Attach', 'Info', mb_Ok);
    DLL_PROCESS_DETACH:
    MessageBox(DLLHandle, 'Process Detach', 'Info', mb_Ok);
    end;
    end;

    begin
    DllProc := @DLLEntryPoint;
    DllEntryPoint(DLL_PROCESS_ATTACH);
    end.
    用法:InjectDLL(‘testDLL.dll’, ‘yourapplication.exe’)

    二. delphi远程直接注入代码执行(非DLL插入是代码注入)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    //-------------------------注入代码的函数----------------------------  
    {参数说明:
    InHWND:被注入的窗口句柄
    Func:注入的函数的指针
    Param:参数的指针
    ParamSize:参数的大小
    }
    procedure InjectFunc(InHWND: HWND; Func: Pointer; Param: Pointer; ParamSize: DWORD);
    var
    hProcess_N: THandle;
    ThreadAdd, ParamAdd: Pointer;
    hThread: THandle;
    ThreadID: DWORD;
    lpNumberOfBytes:DWORD;
    begin
    GetWindowThreadProcessId(InHWND, @ThreadID); //获得窗口ID
    hProcess_N := OpenProcess(PROCESS_ALL_ACCESS, False, ThreadID);//打开被注入的进程
    ThreadAdd := VirtualAllocEx(hProcess_N, nil, 4096, MEM_COMMIT, PAGE_READWRITE); //申请写入代码空间
    WriteProcessMemory(hProcess_N, ThreadAdd, Func, 4096, lpNumberOfBytes); //写入函数地址
    ParamAdd := VirtualAllocEx(hProcess_N, nil, ParamSize, MEM_COMMIT, PAGE_READWRITE); //申请写入代码参数空间
    WriteProcessMemory(hProcess_N, ParamAdd, Param, ParamSize, lpNumberOfBytes); //写入参数地址
    hThread := CreateRemoteThread(hProcess_N, nil, 0, ThreadAdd, ParamAdd, 0, lpNumberOfBytes); //创建远程线程
    ResumeThread(hThread); //直接运行线程
    CloseHandle(hThread); //关闭线程
    VirtualFreeEx(hProcess_N, ThreadAdd, 4096, MEM_RELEASE);
    VirtualFreeEx(hProcess_N, ParamAdd, ParamSize, MEM_RELEASE); //释放申请的地址
    CloseHandle(hProcess_N); //关闭打开的句柄
    end;
    //-----------------------------定义一个参数类型-----------------------
    type
    TPickCallParam = packed record
    ax, ay: single;
    end;
    PPickCallParam = ^TPickCallParam; //指向结构的指针(C中叫这种方式的数据应该叫结构体吧)
    procedure runCall(p:PPickCallParam);stdcall; // 走路call
    var
    addres,addres1,addres2:pointer;
    x,y:single;
    begin
    addres:=pointer($0045ec00);
    addres1:=pointer($00462620);
    addres2:=pointer($0045f000);
    x:=p^.ax; //目的地X坐标
    y:=p^.ay; //目的地Y坐标
    asm
    pushad
    mov eax, dword ptr [$8f207c]
    mov eax, dword ptr [eax+$1C]
    mov esi, dword ptr [eax+$20]
    mov ecx, dword ptr [esi+$ba0]
    push 1
    call addres
    mov edi, eax
    lea eax, dword ptr [esp+$18]
    push eax
    push 0
    mov ecx, edi
    call addres1
    push 0
    push 1
    push edi
    mov ecx, dword ptr [esi+$ba0]
    push 1
    call addres2
    mov eax, dword ptr [$8f207c]
    mov eax, dword ptr [eax+$1C]
    mov eax, dword ptr [eax+$20]
    mov eax, dword ptr [eax+$ba0]
    mov eax, dword ptr [eax+$30]
    mov ecx, dword ptr [eax+4]
    mov eax, x
    mov [ecx+$20], eax
    mov eax, y
    mov [ecx+$28], eax
    popad
    end;
    END;
    procedure TForm1.Button1Click(Sender: TObject);//在控件中做个按钮 测试
    var
    CallParam:TPickCallParam;
    begin;
    getmem(pname,33);
    myhwnd := FindWindow(nil,'Element Client');{查找窗口句柄}
    GetWindowThreadProcessId(myhwnd, aproc); {得到窗口ID}
    phnd := OpenProcess(PROCESS_VM_READ , False, aproc);{以完全访问权限打开进程句柄}
    if (phnd<>0 ) then
    begin
    CallParam.ax:= 1860.0; //给注入代码函数赋值
    CallParam.ay:=120.0; //给注入代码函数赋值
    InjectFunc(myhWnd,@runCall,@CallParam,SizeOf(CallParam)); //运行注入代码函数
    sleep(100);
    CloseHandle(PHND) //关闭进程
    end;
    end;

    三. 远程代码或DLL注入x86/x64/Win2k/win7~Win8.1 64位全可用(最重要的隆重登场)

    上面的一和二远程注入,在win7 64位系统下,不能成功注入service服务程序,下面代码实现在64位系统,可以注入系统进程,服务进程等!看关键函数NtCreateThreadEx,而在win7 64位下的注入问题http://forum.sources.ru/index.php?showtopic=313636有相应讨论
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    program Inject;

    {$APPTYPE CONSOLE}


    {$IF CompilerVersion >= 21.0}
    {$WEAKLINKRTTI ON}
    {$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
    {$IFEND}

    uses
    Winapi.Windows;

    Type
    NtCreateThreadExProc = Function(Var hThread:THandle; Access:DWORD; Attributes:Pointer; hProcess:THandle; pStart:Pointer; pParameter:Pointer; Suspended:BOOL; StackSize, u1, u2:DWORD; Unknown:Pointer):DWORD; stdcall;


    Function CheckOs():Boolean;
    Var
    lpVersionInformation :TOSVersionInfoW;
    begin
    Result := False;
    if GetVersionExW(lpVersionInformation) then
    begin
    if lpVersionInformation.dwPlatformId = VER_PLATFORM_WIN32_NT Then
    begin
    if (lpVersionInformation.dwMajorVersion < 6) then
    begin
    Result := True;
    end;
    end;
    end;
    end;

    Function EnableDebugPrivilege():Boolean;
    Var
    hToKen :THandle;
    TokenPri :TTokenPrivileges;
    begin
    Result := False;
    if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES, hToKen)) Then
    begin
    TokenPri.PrivilegeCount := 1;
    If LookupPrivilegeValueW(Nil, 'SeDebugPrivilege', TokenPri.Privileges[0].Luid) Then
    begin
    TokenPri.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
    Result := AdjustTokenPrivileges(hToken, False, TokenPri, SizeOf(TTokenPrivileges), Nil, PDWORD(Nil)^);
    end Else Writeln('LookupPrivilege Error');
    CloseHandle(hToKen);
    end;
    end;

    Function RemoteThread(hProcess:THandle; pThreadProc:Pointer; pRemote:Pointer):THandle;
    Label NtCreate, Create;
    Var
    pFunc :Pointer;
    hThread :THandle;
    begin
    hThread := 0;
    if Not CheckOs() then //根据系统版本来选择使用的API
    begin
    NtCreate:
    pFunc := GetProcAddress(LoadLibraryW('ntdll.dll'), 'NtCreateThreadEx');
    if pFunc = Nil then Goto Create;
    NtCreateThreadExProc(pFunc)(hThread, $1FFFFF, Nil, hProcess, pThreadProc, pRemote, False, 0, 0, 0, Nil);
    if hThread = 0 then Goto Create;
    end Else
    begin
    Create:
    hThread := CreateRemoteThread(hProcess, Nil, 0, pThreadProc, pRemote, 0, PDWORD(Nil)^);
    end;
    Writeln('RemoteThread Ok!');
    Result := hThread;
    end;

    Function InjectDll2Pid(szPath:PWideChar; uPID:DWORD):Boolean;
    Var
    hProcess :THandle;
    hThread :THandle;
    szRemote :PWideChar;
    uSize :SIZE_T;
    uWrite :SIZE_T;
    pStartAddr:Pointer;
    begin
    Result := False;
    if EnableDebugPrivilege then
    begin //先提升下进程的权限
    hProcess := OpenProcess(PROCESS_ALL_ACCESS, false, uPID);
    if hProcess > 0 then
    begin
    uSize := lstrlenW(szPath) * 2 + 4;
    szRemote := VirtualAllocEx(hProcess, Nil, uSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if WriteProcessMemory(hProcess, szRemote, szPath, uSize, uWrite) And (uWrite = uSize) then
    begin
    pStartAddr := GetProcAddress(LoadLibrary('Kernel32.dll'), 'LoadLibraryW');
    hThread := RemoteThread(hProcess, pStartAddr, szRemote);
    Result := hThread <> 0;
    CloseHandle(hThread);
    end Else
    begin
    Writeln('WriteMemory Error');
    end;
    end;
    end;
    end;

    Function StrToInt(S: String): Integer;
    Var
    E: Integer;
    Begin
    Val(S, Result, E);
    End;

    begin
    InjectDll2Pid(PWideChar(ParamStr(2)), StrToInt(ParamStr(1)));
    end.

    NtCreateThreadEx注入注意事项:

    64位的进程,只能使用64位的dll注入,注入程序本身也必须编译为64位程序,32位的进程,只能使用32位的dll注入,注入程序本身编译为32位程序,不然会注入不成功!比如你把程序编译为32程序,想在win7 64位下往services.exe注入,是不会成功的,services.exe在win7 64位下是64位程序!
-------------本文已结束赏个小钱吧-------------
×

感谢您的支持,我们会一直保持!

扫码支持
请土豪扫码随意打赏

打开微信扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

64.7K

相关文章推荐