A程序 B文件都是不可改的东西A程序要读取B文件  会调用哪个API?我的目的:是要HOOK A程序,在读取B文件时实现调用自定义函数对B文件进行解密,然后再调用原API说白了就是要对B文件加密,让A直接读取加密文件,防止B文件被盗。有什么好的思路  欢迎大家踊跃发言

解决方案 »

  1.   

    读取?creatfile,readfile都有可能
      

  2.   

    參考一下:
    本程式來自EurekaLog for Delphi中的EHook.pas,
    經過修改後可以單獨運行.
    本單元實現了兩種API Hook技術.
    一是採用了更改各個模組中函數入口指標,實現各模組調用API時被 Hook.優點是可以選擇性的對某個模組(OCX,DLL..)訪問
    某個API時被hook.
    二是採用了所有模組都被Hook,通過修改API函數第一條指令為跳轉到使用者API,備份原API內容.用戶可以在自己定義的API上調用原來的API.
    本單元還實現了UnHook.
    是一個較完整的API Hook 庫程式
    有興趣的朋友可以將這個API Hook Lib擴展到對其他進程的API Hook.
    本文末尾將介紹兩種Hook技術的使用方法.1.
    EHookLib.pas:
    代碼:
    {************************************************}
    {                                                }
    {               EurekaLog v 6.x                  }
    {              Hook Unit - EHook                 }
    {                                                }
    {  Copyright (c) 2001 - 2007 by Fabio Dell'Aria  }
    {                                                }
    {************************************************}unit EHookLIB;//{$I Exceptions.inc}interfaceuses Windows; type
      THandle = Cardinal;
      PPointer = ^Pointer;
      PShortInt = ^ShortInt;function HookProcedureEx(ProcAddr, NewProc: Pointer; ProcName: string): Pointer;
    function UnhookProcedure(ProcAddr: Pointer): Boolean;function HookDllProcedureEx(ImportModule, ExportModule, ProcName: string;
      NewProc: Pointer): Pointer;
    function TryHookDllProcedureEx(ImportModules: array of string;
      ExportModule, ProcName: string; NewProc: Pointer;
      var CallProc: Pointer; CanFail: Boolean): Boolean;
    function TryHookProcedureEx(ExportModule, ProcName: string; NewProc: Pointer;
      var CallProc: Pointer): Boolean;function HookVirtualMethod(AClass: TClass; Index: Integer; Method: Pointer): Pointer;
    function UnhookVirtualMethod(AClass: TClass; Index: Integer): Boolean;procedure JumpToMem(Addr, Jump: Pointer);function GetFunctionSize(Addr, MaxSize: DWord): DWord;
    function GetAsmSize(Start: Pointer; var Size: Byte): Boolean;var
      CriticalError: procedure (const Section: string) = nil;implementationuses Classes, SysUtils;const
      EProcNullStr = 'Cannot hook a null procedure ("%s").';
      ESharedAreaStr = 'Cannot hook the module "%s" located into the shared-area.';
      EHookingErrorStr = 'Cannot hook the procedure "%s".';  SharedMem = $7FFFFFFF; // Don't use major value because Delphi3 don't support it.  ModRmMod = $C0; // XX??????
      ModRmRM = $07; //  ?????XXX  OperSizeOver = $66; // Change the operand size from 32 to 16/8 bits.
      AddrSizeOver = $67; // Change the address size from 32 to 16/8 bits.  OpCodePrefixes: set of Byte =
        [$F0, $F2, $F3, $2E, $36, $3E, $26, $64, $65, OperSizeOver, AddrSizeOver];  OpCodeShortJump: set of Byte = [$70..$7F, $E0..$E3, $EB]; // 1 OpCode byte  OpCodeReturn: set of Byte = [$C2, $C3..$CA, $CB]; // "Return" first byte OpCodes  OpCodeLongJump1Byte: set of Byte = [$E8..$E9]; // 1 OpCode byte  OpCodeLongJump2Bytes: set of Byte = [$80..$8F]; // 2 OpCode bytes, 1th = $0F  AsmConst: array [0..255] of Byte = ($EE, $EE, $EE, $EE, $F1, $0B, $00, $00,
        $0E, $0E, $FE, $FE, $F1, $EB, $00, $FF, $EE, $EE, $EE, $EE, $E1, $EB, $E0,
        $E0, $EE, $FE, $FE, $FE, $F1, $FB, $F0, $F0, $EE, $EE, $EE, $EE, $F1, $FB,
        $FF, $F0, $EE, $EE, $EE, $EE, $E1, $EB, $EF, $E0, $0E, $0E, $0E, $0E, $01,
        $0B, $FF, $F0, $FE, $FE, $FE, $FE, $F1, $FB, $FF, $F0, $E0, $E0, $E0, $E0,
        $E0, $E0, $E0, $E0, $E0, $E0, $E0, $E0, $E0, $E0, $E0, $E0, $E0, $E0, $E0,
        $E0, $E0, $E0, $E0, $E0, $E0, $E0, $E0, $E0, $E0, $E0, $E0, $E0, $E0, $E0,
        $EE, $EE, $EF, $EF, $EF, $EF, $EB, $EE, $E1, $EE, $F0, $F0, $E0, $E0, $E1,
        $E1, $E1, $E1, $E1, $E1, $E1, $01, $F1, $F1, $F1, $F1, $F1, $F1, $E1, $E1,
        $BE, $BE, $BE, $BE, $BE, $BE, $BE, $BE, $BE, $BE, $BE, $BE, $BE, $BE, $BE,
        $BE, $E0, $E0, $E0, $E0, $E0, $E0, $E0, $E0, $E0, $E0, $ED, $E0, $E0, $E0,
        $E0, $E0, $04, $04, $04, $E4, $E0, $E0, $E0, $E0, $01, $0B, $00, $E0, $E0,
        $E0, $E0, $E0, $E1, $E1, $E1, $E1, $E1, $E1, $E1, $E1, $FB, $FB, $EB, $EB,
        $EB, $EB, $EB, $EB, $EE, $EE, $E2, $E0, $EE, $EE, $EE, $EE, $03, $00, $02,
        $00, $00, $01, $00, $00, $FE, $EE, $EE, $EE, $E1, $E1, $F0, $E0, $EE, $EE,
        $EE, $EE, $EE, $EE, $EE, $EE, $E1, $E1, $E1, $E1, $E1, $E1, $F1, $E1, $EB,
        $EB, $ED, $E1, $E0, $E0, $E0, $E0, $FF, $E0, $EF, $EF, $E0, $E0, $EE, $EE,
        $E0, $E0, $E0, $E0, $E0, $E0, $EE, $FE);type
      EHookError = class(Exception);
      EProcNull = class(EHookError);
      EHookingError = class(EHookError);
      ESharedArea = class(EHookError);  EIgnoreException = class(Exception);
      TProc = procedure;  TRedirectOpCodes = packed record
        JMPOpCode: Byte;
        JMPDistance: DWord;
      end;  TPrefixes = set of Byte;  THookedProcedure = record
        OriginalProc, HookedBlockPt: Pointer;
        HookedBlockSize: DWord;
        POriginalAsmPt: Pointer;
        POriginalAsmSize: DWord;
      end;
      PHookedProcedure = ^ THookedProcedure;  PSaveDLLProc = ^TSaveDLLProc;
      TSaveDLLProc = packed record
        HookModule: THandle;
        ExportModule: string;
        OldProc, NewProc: Pointer;
      end;  THookedData = packed record
        ClassType: TClass;
        OriginalMethod: Pointer;
        Index: Integer;
      end;
      PHookedData = ^THookedData;  PWin9xDebugThunk = ^TWin9xDebugThunk;
      TWin9xDebugThunk = packed record
        PUSH: Byte;    // PUSH instruction opcode ($68)
        Addr: Pointer; // The actual address of the DLL routine
        JMP: Byte;     // JMP instruction opcode ($E9)
        Rel: Integer;  // Relative displacement (a Kernel32 address)
      end;  IMAGE_IMPORT_DESCRIPTOR = packed record
        UnUsed: array [0..11] of Byte;
        Name: DWord;
        FirstThunk: DWord;  // RVA to IAT
      end;
      PImageImportDescriptor = ^IMAGE_IMPORT_DESCRIPTOR;  IMAGE_THUNK_DATA = packed record
        Function_: DWord; // PDWord
      end;
      PImageThunkData = ^IMAGE_THUNK_DATA;  PImageDosHeader = ^TImageDosHeader;
      TImageDosHeader = packed record    // DOS .EXE header
          e_magic: Word;                 // Magic number
          UnUsed: array [0..57] of Byte;
          _lfanew: LongInt;              // File address of new exe header
      end;  THookedMethodsList = class(TList)
      private
        FLock: TRTLCriticalSection;
        function GetItem(Index: Integer): PHookedData;
      protected
      public
        constructor Create;
        destructor Destroy; override;
        procedure Lock;
        procedure Unlock;
        procedure Delete(Index: Integer);
        property Items[Index: Integer]: PHookedData read GetItem; default;
      end;const
      TRedirectOpCodesSize = SizeOf(TRedirectOpCodes);var
      HookedProcedures, DllList: TList;
      HookedMethodsList: THookedMethodsList;//------------------------------------------------------------------------------{ THookedMethods }constructor THookedMethodsList.Create;
    begin
      inherited;
      InitializeCriticalSection(FLock);
    end;function THookedMethodsList.GetItem(Index: Integer): PHookedData;
    begin
      Result := PHookedData(TList(Self).Items[Index]);
    end;procedure THookedMethodsList.Lock;
    begin
      EnterCriticalSection(FLock);
    end;procedure THookedMethodsList.Unlock;
    begin
      LeaveCriticalSection(FLock);
    end;procedure THookedMethodsList.Delete(Index: Integer);
    var
      Data: PHookedData;
      Ptr: Pointer;
    begin
      Ptr := Items[Index];
      Data := PHookedData(Ptr);
      Dispose(Data);
      inherited;
    end;destructor THookedMethodsList.Destroy;
    var
      I: Integer;
    begin
      Lock;
      try
        for I := 0 to HookedMethodsList.Count - 1 do
          UnhookVirtualMethod(HookedMethodsList[0]^.ClassType, HookedMethodsList[0]^.Index);
      finally
        Unlock;
      end;
      DeleteCriticalSection(FLock);
      inherited;
    end;//------------------------------------------------------------------------------function GetReadableSize(Address, Size: DWord): DWord;
    const
      ReadAttributes = [PAGE_READONLY, PAGE_READWRITE, PAGE_WRITECOPY, PAGE_EXECUTE,
        PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_EXECUTE_WRITECOPY];
    var
      MemInfo: TMemoryBasicInformation;
      Tmp: DWord;
    begin
      Result := 0;
      if (VirtualQuery(Pointer(Address), MemInfo, SizeOf(MemInfo)) = SizeOf(MemInfo)) and
        (MemInfo.State = MEM_COMMIT) and (MemInfo.Protect in ReadAttributes) then
      begin
        Result := (MemInfo.RegionSize - (Address - DWord(MemInfo.BaseAddress)));
        if (Result < Size) then
        begin
          repeat
            Tmp := GetReadableSize((DWord(MemInfo.BaseAddress) + MemInfo.RegionSize), (Size - Result));
            if (Tmp > 0) then Inc(Result, Tmp)
            else Result := 0;
          until (Result >= Size) or (Tmp = 0);
        end;
      end;
    end;
      

  3.   

    2.上接:
     function IsValidBlockAddr(Address, Size: DWord): Boolean;
    begin
      Result := (GetReadableSize(Address, Size) >= Size);
    end;function ConvertAddress(Addr: DWord): DWord;
    type
      TJMPCode = packed record
        JMPOpCode: Word;
        JMPPtr: PDWord;
        MOVOpCode: Word;
      end;
      PJMPCode = ^TJMPCode;
    var
      JMP: PJMPCode;
    begin
      Result := Addr;
      if (IsValidBlockAddr(Addr, 8)) then
      begin
        JMP := PJMPCode(Addr);
        if (JMP^.JMPOpCode = $25FF) and (IsValidBlockAddr(DWord(JMP^.JMPPtr), 4)) then
          Result := JMP^.JMPPtr^;
      end;
    end;//------------------------------------------------------------------------------function GetVirtualMethod(AClass: TClass; const Index: Integer): Pointer;
    begin
      Result := PPointer(Integer(AClass) + (Index * 4))^
    end;procedure SetVirtualMethod(AClass: TClass; Index: Integer; Method: Pointer);
    var
      PatchAddress: PPointer;
      OldProtectionCode: DWord;
    begin
      PatchAddress := PPointer(Integer(AClass) + (Index * 4));
      if (FindHInstance(PatchAddress) = 0) then Exit; // Check for unloaded module...
      VirtualProtect(PatchAddress, 4, PAGE_EXECUTE_READWRITE, @OldProtectionCode);
      PatchAddress^ := Method;
      VirtualProtect(PatchAddress, 4, OldProtectionCode, @OldProtectionCode);
      FlushInstructionCache(GetCurrentProcess, PatchAddress, 4);
    end;function HookVirtualMethod(AClass: TClass; Index: Integer; Method: Pointer): Pointer;
    var
      HData: PHookedData;
      n: Integer;
    begin
      Result := nil;
      if (Assigned(HookedMethodsList)) then
      begin
        HookedMethodsList.Lock;
        try
          Result := GetVirtualMethod(AClass, Index);
          if (Result = Method) then
          begin // Just hooked...
            for n := 0 to (HookedMethodsList.Count - 1) do
            begin
              if ((HookedMethodsList[n]^.ClassType = AClass) and
              (HookedMethodsList[n]^.Index = Index)) then
              begin
                Result := HookedMethodsList[n]^.OriginalMethod;
                Break;
              end;
            end;
          end
          else
          begin // First hook...
            SetVirtualMethod(AClass, Index, Method);
            New(HData);
            HData^.ClassType := AClass;
            HData^.OriginalMethod := Result;
            HData^.Index := Index;
            HookedMethodsList.Add(HData);
          end;
        finally
          HookedMethodsList.Unlock;
        end;
      end;
    end;function UnhookVirtualMethod(AClass: TClass; Index: Integer): Boolean;
    var
      n: Integer;
    begin
      Result := False;
      if (Assigned(HookedMethodsList)) then
      begin
        HookedMethodsList.Lock;
        try
          for n := 0 to (HookedMethodsList.Count - 1) do
          begin
            if ((HookedMethodsList[n]^.ClassType = AClass) and
            (HookedMethodsList[n]^.Index = Index)) then
            begin
              SetVirtualMethod(AClass, Index, HookedMethodsList[n]^.OriginalMethod);
              HookedMethodsList.Delete(n);
              Result := True;
              Break;
            end;
          end;
        finally
          HookedMethodsList.Unlock;
        end;
      end;
    end;
      

  4.   

    可以用一些HOOK,HOOK 系统API readfile,readfileex之类的就行了
      

  5.   

    3.只能回覆三次,PAS太長了,LZ還是提供一個油箱吧,我將文件發給你,自己動手測試一下試試看,這裡先省略部分PAS代碼,把調用部分貼出來,供你參考function TryHookDllProcedureEx(ImportModules: array of string;
      ExportModule, ProcName: string; NewProc: Pointer;
      var CallProc: Pointer; CanFail: Boolean): Boolean;
    var
      TmpProc, OldProc: Pointer;
      HModule: THandle;
      n: integer;
    begin
      Result := False;
      OldProc := GetProcAddress(GetModuleHandle(PChar(ExportModule)), PChar(ProcName));  for n := low(ImportModules) to high(ImportModules) do
      begin
        HModule := GetModuleHandle(PChar(ImportModules[n]));
        if (HModule <> 0) then
        begin
          TmpProc := HookDllProcedure(HModule, ExportModule, OldProc, NewProc,
            ExportModule + '.' + ProcName, CanFail, False);
          Result := (Result) or (TmpProc <> nil);
        end;
      end;  CallProc := OldProc; // WARNING don't move to HERE!!!
    end;function TryHookProcedureEx(ExportModule, ProcName: string; NewProc: Pointer;
      var CallProc: Pointer): Boolean;
    var
      TmpProc, OldProc: Pointer;
    begin
      Result := False;
      OldProc := GetProcAddress(GetModuleHandle(PChar(ExportModule)), PChar(ProcName));  TmpProc := nil;
      if Assigned(OldProc) then TmpProc := HookProcedureEx(OldProc, NewProc, ProcName);  Result := (Result) or (TmpProc <> nil);
      CallProc := TmpProc; // WARNING don't move to HERE!!!
    end;function HookDllProcedureEx(ImportModule, ExportModule, ProcName: string;
      NewProc: Pointer): Pointer;
    var
      OldProc: Pointer;
    begin
      OldProc := GetProcAddress(GetModuleHandle(PChar(ExportModule)), PChar(ProcName));  Result := HookDllProcedure(GetModuleHandle(PChar(ImportModule)), ExportModule,
        OldProc, NewProc, ExportModule + '.' + ProcName, False, False);
    end;//------------------------------------------------------------------------------procedure Init;
    begin
      DllList := TList.Create;
      HookedMethodsList := THookedMethodsList.Create;
      HookedProcedures := TList.Create;
    end;procedure Done;
    var
      n: Integer;
      P: PSaveDLLProc;
      PHookedBlock: PHookedProcedure;
    begin
      for n := 0 to DllList.Count - 1 do
      begin
        P := PSaveDLLProc(DllList[n]);
        HookDLLProcedure(P^.HookModule, P^.ExportModule, P^.NewProc, P^.OldProc, '', True, True);
        Dispose(P);
      end;
      DllList.Free;
      DllList := nil;
      HookedMethodsList.Free;
      HookedMethodsList := nil;
      for n := HookedProcedures.Count - 1 downto 0 do
      begin
        PHookedBlock := HookedProcedures[n];
        UnhookProcedure(PHookedBlock^.OriginalProc);
      end;
      HookedProcedures.Free;
      HookedProcedures := nil;
    end;//------------------------------------------------------------------------------
    procedure SafeExec(Proc: TProc; Section: string);
    var
      Error: string;
    begin
      try
        Proc;
      except
        on Err: TObject do
        begin
          if (Err is EIgnoreException) then raise;      if (@CriticalError <> nil) then
          begin
            CriticalError(Format('%s (Address: %s)', [Section, IntToHex(DWord(@Proc), 8)]));
            Abort;
          end
          else
          begin
            if (ExceptObject is Exception) then Error := Exception(ExceptObject).Message
            else Error := 'General internal error.';
            raise Exception.CreateFmt('Critical error at: "%s"'#13#10'Error: "%s".', [Section, Error]);
          end;
        end;
      end;
    end;//------------------------------------------------------------------------------
    initialization
      SafeExec(Init, 'EHook.Init');finalization
      SafeExec(Done, 'EHook.Done');end.
    下麵是示例程式:
    代碼:
    type
      //保存原API函數位址
      Kernel_WriteFile: function(hFile: Integer; const Buffer; nNumberOfBytesToWrite: Cardinal;
        var lpNumberOfBytesWritten: Cardinal; lpOverlapped: Pointer): Integer; stdcall;
      //自訂api函數
    function MyWriteFile(hFile: THandle; Buffer:PPChar; nNumberOfBytesToWrite: DWORD;
      var lpNumberOfBytesWritten: DWORD; lpOverlapped: POverlapped): BOOL; stdcall;
    var
      i:DWORD;
    begin
       //將所有寫入的資料取反
        for i:=LongWord(Buffer) to LongWord(Buffer)+nNumberOfBytesToWrite-1 do
        begin
          A:=PByte(i)^;
          A:=not A;
          PByte(i)^:=A;
        end;
      //調用原來的系統檔
      Result:=Kernel_WriteFile(hFile, Buffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
    end;
    上面準備好了使用者自訂API,和保存系統API函數指標.
    下面介紹用法:
    1.對單獨模組進行API Hook
    例如,假設我們的程式中包括了Mapx5.ocx, lin.dll和其他一些dll模組,
    我們只想Hook程式的MapX5.OCX和 Lin.dll兩個模組的WriteFile這個API函數,
    調用函數TryHookDllProcedureEx:
    代碼:
       S:=ExtractFilePath(Application.ExeName);//獲取路徑
        // Hooked "WriteFile" Windows API...
        TryHookDllProcedureEx(
          [S+'MapX5.OCX', S+'Lin.dll'], //僅改變Mapx5.ocx, lin.dll兩個模組的WriteFile功能
          kernel32, 'WriteFile',
          @HookedWriteFile, @Kernel_WriteFile, True);
    2.對所有模組進行API Hook
    更簡單,調用函數TryHookProcedureEx
    代碼:
      TryHookProcedureEx(
        kernel32, 'CreateFileA',
        @MyCreateFileA, @Kernel_CreateFileA);
    Unhook某個函數:
    更更簡單,調用  UnHookProcedure:
    代碼:
      UnHookProcedure(@Kernel_WriteFile);
      

  6.   

    一步一步來,既然有EurekaLog,那麼HOOK程序A是沒有問題了,再用其API之readfile之類,調用你的自定義函數進行讀取文件的加解密操作應該沒有什麼問題
      

  7.   

    LZ既然说B文件也是不可改的,那你怎么对它加密,加密就要修改。
      

  8.   

    B文件整个加密后替换让A直接读取加密后的B文件我的想法是HOOK读取文件时的API  首先对B文件解密在调用原API就是不知道到底该HOOK哪个API函数有没有什么工具 可以查看程序运行时的API函数??
      

  9.   

    IDA、ollydbg、会用简单,不会用就算了
      

  10.   

    要先对B文件解密,然后再加密,建议LZ用两种以上加密方法交替使用,以防解密过程泄密;
      

  11.   

    为什么不直接存贮加密的文件呢?使之只有在某进程读取时候才能获得正常的数据。否则的话普通Hook太容易被攻破了,写个Console程序就可以绕过Hook了