Delphi皮膚控制元件去NAG提示

williamlv發表於2024-07-21

國外某知名皮膚控制元件,一些好看的皮膚會彈出對話方塊....

用查詢控制代碼的方法去發訊息關閉對話方塊,都不得行...,以為是屏敝了訊息,自定義訊息也失效。

後面用修改記憶體地址指令的方法,就可以有效的去掉NAG提示

此貼僅做為技術研討,請支援正版!

function FindPattern(ProcessHandle: THandle; StartAddr, EndAddr: DWORD; const Pattern: array of Byte; PatternSize: Integer): DWORD;
var
  Buffer: array of Byte;
  BytesRead: Cardinal;
  CurrentAddr: DWORD;
  i: Integer;
begin
  SetLength(Buffer, EndAddr - StartAddr);
  // 讀取整個記憶體區域
  if ReadProcessMemory(ProcessHandle, Pointer(StartAddr), @Buffer[0], Length(Buffer), BytesRead) then
  begin
    for CurrentAddr := StartAddr to EndAddr - PatternSize do
    begin
      for i := 0 to PatternSize - 1 do
      begin
        if Buffer[CurrentAddr - StartAddr + i] <> Pattern[i] then
          Break;
        if i = PatternSize - 1 then
        begin
          Result := CurrentAddr; // 找到目標地址,返回找到的地址
          Exit; // 退出函式
        end;
      end;
    end;
  end;
  Result := 0; // 沒有找到
end;

procedure PatchMemory;
var
  ProcessID: DWORD;
  ProcessHandle: THandle;
  StartAddr, EndAddr: DWORD;
  AddressFound: DWORD;
  OldProtect: DWORD; // 用於儲存舊的保護屬性
  I: Integer;
const
  TARGET_INSTRUCTION: array[0..4] of Byte = ($68, $40, $00, $06, $00);  // 定義特徵碼
  PROCESS_READ_MEMORY = $0010; // 定義 PROCESS_READ_MEMORY 常量
begin
  ProcessHandle := 0; // 初始化程序控制代碼
  try
    ProcessID := GetCurrentProcessId; // 獲取目標程序的ID
    // 開啟目標程序
    ProcessHandle := OpenProcess(PROCESS_READ_MEMORY, False, ProcessID);
    if ProcessHandle = 0 then
    begin
      ShowMessage('無法開啟程序: ' + SysErrorMessage(GetLastError));
      Exit;
    end;
    // 定義搜尋記憶體的範圍
    StartAddr := $0057D73D; // 搜尋起始地址
    EndAddr := $0057D8AF;  // 結束地址
    // 查詢目標地址
    AddressFound := FindPattern(ProcessHandle, StartAddr, EndAddr, TARGET_INSTRUCTION, Length(TARGET_INSTRUCTION));
    if AddressFound <> 0 then
    begin  
     // 修改記憶體保護為可讀寫執行
      if VirtualProtect(Pointer(AddressFound), 21, PAGE_EXECUTE_READWRITE, OldProtect) then
      begin
        try
          for I := 0 to 21 do  //修改22個基址
          begin
        // 寫入 NOP 指令 (0x90)
            PByte(Pointer(AddressFound + I))^ := $90;
          end;
        finally
      // 還原原來的記憶體保護
          VirtualProtect(Pointer(AddressFound), 21, OldProtect, @OldProtect);
        end;
      end
      else
      begin
        ShowMessage('無法更改記憶體保護屬性, 地址: ' + IntToHex(AddressFound, 8));
      end;
    end;
  except
    on E: Exception do
      ShowMessage('發生異常: ' + E.Message);
  end;
  // 關閉程序控制代碼
  if ProcessHandle <> 0 then
    CloseHandle(ProcessHandle);
end;

procedure TForm1.sSkinManager1BeforeChange(Sender: TObject);
begin 
   PatchMemory;
end;

相關文章