• delphi dll 注入弹dll内的窗口


    注入exe
    //
    给出exename 找到pid function GetExePid(const aExeName: string):Cardinal; var _vHandle : THandle; _vProEntry : TProcessEntry32; _vIsFound : Boolean; _vProHandle : THandle; _vHmodule : HMODULE; _vFileNameBuf : array[0..MAX_PATH] of Char; _vNeeded : DWORD; _vTempStr : string; begin Result := 0; _vHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); try _vProEntry.dwSize := SizeOf(TProcessEntry32); _vIsFound := Process32First(_vHandle, _vProEntry); while _vIsFound do begin _vTempStr := _vProEntry.szExeFile; if (UpperCase(_vTempStr) = UpperCase(ExtractFileName(aExeName))) or (UpperCase(_vTempStr) = UpperCase(aExeName)) then begin Result := _vProEntry.th32ProcessID; break; end; _vIsFound := Process32Next(_vHandle, _vProEntry); end; finally CloseHandle(_vHandle); end; end; function AdjustProcessPrivilege(ProcessHandle: THandle; Token_Name: Pchar): boolean; var Token: THandle; TokenPri: _TOKEN_PRIVILEGES; ProcessDest: int64; l: DWORD; begin Result := False; if OpenProcessToken(ProcessHandle, TOKEN_ADJUST_PRIVILEGES, Token) then begin if LookupPrivilegeValue(nil, Token_Name, ProcessDest) then begin TokenPri.PrivilegeCount := 1; TokenPri.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED; TokenPri.Privileges[0].Luid := ProcessDest; l := 0; //更新进程令牌,成功返回TRUE if AdjustTokenPrivileges(Token, False, TokenPri, sizeof(TokenPri), nil, l) then begin Form1.mmo1.Lines.Add('更新进程令牌成功!'); Result := True; end; end; end; end; function EnableDebugPriv: Boolean; var hToken: THandle; tp: TTokenPrivileges; rl: Cardinal; begin Result := false; //打开进程令牌环 OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken); //获得进程本地唯一ID if LookupPrivilegeValue(nil, 'SeDebugPrivilege', tp.Privileges[0].Luid) then begin tp.PrivilegeCount := 1; tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED; //调整权限 Result := AdjustTokenPrivileges(hToken, false, tp, SizeOf(tp), nil, rl); end; end; //注入dll function InjectDll(const DllFullPath: string; const dwRemoteProcessId: Cardinal): Boolean; var hRemoteProcess, hRemoteThread: THandle; pszLibFileRemote: Pointer; pszLibAFilename: PwideChar; pfnStartAddr: TFNThreadStartRoutine; memSize, WriteSize, lpThreadId: Cardinal; begin Result := false; // 调整权限,使程序可以访问其他进程的内存空间 if EnableDebugPriv then begin //打开远程线程 PROCESS_ALL_ACCESS 参数表示打开所有的权限 hRemoteProcess := OpenProcess(PROCESS_ALL_ACCESS, false, dwRemoteProcessId); try // 为注入的dll文件路径分配内存大小,由于为WideChar,故要乘2 GetMem(pszLibAFilename, Length(DllFullPath) * 2 + 1); // 之所以要转换成 WideChar, 是因为当DLL位于有中文字符的路径下时不会出错 StringToWideChar(DllFullPath, pszLibAFilename, Length(DllFullPath) * 2 + 1); // 计算 pszLibAFilename 的长度,注意,是以字节为单元的长度 memSize := (1 + lstrlenW(pszLibAFilename)) * SizeOf(WCHAR); //使用VirtualAllocEx函数在远程进程的内存地址空间分配DLL文件名空间 pszLibFileRemote := VirtualAllocEx(hRemoteProcess, nil, memSize, MEM_COMMIT, PAGE_READWRITE); if Assigned(pszLibFileRemote) then begin //使用WriteProcessMemory函数将DLL的路径名写入到远程进程的内存空间 if WriteProcessMemory(hRemoteProcess, pszLibFileRemote,pszLibAFilename, memSize, WriteSize) and (WriteSize = memSize) then begin lpThreadId := 0; // 计算LoadLibraryW的入口地址 pfnStartAddr := GetProcAddress(LoadLibrary('Kernel32.dll'),'LoadLibraryW'); // 启动远程线程LoadLbraryW,通过远程线程调用创建新的线程 hRemoteThread := CreateRemoteThread(hRemoteProcess, nil,0, pfnStartAddr, pszLibFileRemote, 0, lpThreadId); // 如果执行成功返回 True; if (hRemoteThread <> 0) then begin Form1.mmo1.Lines.Add('注入成功'); Result := true; end; // 释放句柄 CloseHandle(hRemoteThread); end; end; finally // 释放句柄 CloseHandle(hRemoteProcess); end; end; end; //卸载dll function UnInjectDll(const DllFullPath: string; const dwRemoteProcessId: Cardinal): Boolean; // 进程注入和取消注入其实都差不多,只是运行的函数不同而已 var hRemoteProcess, hRemoteThread: THandle; pszLibFileRemote: PChar; pszLibAFilename: PwideChar; pfnStartAddr: TFNThreadStartRoutine; memSize, WriteSize, lpThreadId, dwHandle: Cardinal; begin // 调整权限,使程序可以访问其他进程的内存空间 if EnableDebugPriv then begin //打开远程线程 PROCESS_ALL_ACCESS 参数表示打开所有的权限 hRemoteProcess := OpenProcess(PROCESS_ALL_ACCESS, false, dwRemoteProcessId); try // 为注入的dll文件路径分配内存大小,由于为WideChar,故要乘2 GetMem(pszLibAFilename, Length(DllFullPath) * 2 + 1); // 之所以要转换成 WideChar, 是因为当DLL位于有中文字符的路径下时不会出错 StringToWideChar(DllFullPath, pszLibAFilename, Length(DllFullPath) * 2 + 1); // 计算 pszLibAFilename 的长度,注意,是以字节为单元的长度 memSize := (1 + lstrlenW(pszLibAFilename)) * SizeOf(WCHAR); //使用VirtualAllocEx函数在远程进程的内存地址空间分配DLL文件名空间 pszLibFileRemote := VirtualAllocEx(hRemoteProcess, nil, memSize, MEM_COMMIT, PAGE_READWRITE); if Assigned(pszLibFileRemote) then begin //使用WriteProcessMemory函数将DLL的路径名写入到远程进程的内存空间 if WriteProcessMemory(hRemoteProcess, pszLibFileRemote, pszLibAFilename, memSize, WriteSize) and (WriteSize = memSize) then begin // 计算GetModuleHandleW的入口地址 pfnStartAddr := GetProcAddress(LoadLibrary('Kernel32.dll'),'GetModuleHandleW'); //使目标进程调用GetModuleHandleW,获得DLL在目标进程中的句柄 hRemoteThread := CreateRemoteThread(hRemoteProcess, nil, 0, pfnStartAddr, pszLibFileRemote, 0, lpThreadId); // 等待GetModuleHandle运行完毕 WaitForSingleObject(hRemoteThread, INFINITE); // 获得GetModuleHandle的返回值,存在dwHandle变量中 GetExitCodeThread(hRemoteThread, dwHandle); // 计算FreeLibrary的入口地址 pfnStartAddr := GetProcAddress(LoadLibrary('Kernel32.dll'),'FreeLibrary'); // 使目标进程调用FreeLibrary,卸载DLL hRemoteThread := CreateRemoteThread(hRemoteProcess, nil,0, pfnStartAddr, Pointer(dwHandle), 0, lpThreadId); // 等待FreeLibrary卸载完毕 WaitForSingleObject(hRemoteThread, INFINITE); // 如果执行成功返回 True; if hRemoteProcess <> 0 then begin Form1.mmo1.Lines.Add('卸载成功'); Result := true; end; // 释放目标进程中申请的空间 VirtualFreeEx(hRemoteProcess, pszLibFileRemote,Length(DllFullPath) + 1, MEM_DECOMMIT); // 释放句柄 CloseHandle(hRemoteThread); end; end; finally // 释放句柄 CloseHandle(hRemoteProcess); end;
    end;
    end;
    
    //调用 注入 
     InjectDll(edt_dll.Text, GetExePid(edt_exe.Text));
    
    //调用卸载
     UnInjectDll(edt_dll.Text, GetExePid(edt_exe.Text));

    dll:

    library project1;
    
    uses
      Forms,
      Windows,
      Unit1 in 'Unit1.pas' {Form1};
    
    //要在新的线程里去创建出来
    procedure WinMain;
    begin
     try
      Form1 := TForm1.Create(nil);
      Form1.ShowModal;
     finally
      FreeAndNil(form1);
      //自己卸载本dll
      FreeLibraryAndExitThread(GetModuleHandle('DecodeDSEFile'), 0);
     end;
    end;
    
    var
     Thread:THandle ;
    begin
     Thread :=GetModuleHandle(nil);
     CreateThread(nil,Thread,@WinMain,nil,0,Thread);
    end.

    注意不能用到qdialogs 单元 不然会崩溃

  • 相关阅读:
    基于mAppWidget实现手绘地图--索引&DEMO
    C语言数据结构----栈的定义及实现
    libvirt命令行文档
    清理系统方法
    Linux 经典电子书共享下载
    使用数组实现队列----《数据结构与算法分析---C语言描述》
    清理系统垃圾
    epoll的内部实现 & 百万级别句柄监听 & lt和et模式非常好的解释
    进程、线程、socket套接字-资源大小 & 切换代价
    网络编程学习-面向工资编程
  • 原文地址:https://www.cnblogs.com/BTag/p/16152941.html
Copyright © 2020-2023  润新知