zoukankan      html  css  js  c++  java
  • madCHook.pas

    //  madCHook.pas          version:  2.0   ?  date: 2003-08-10
    //  ----------
    //  API hooking, code hooking
    //  ----------
    //  Copyright (C) 1999 - 2003 www.madshi.net, All Rights Reserved
    // **********

    // 2003-08-10 2.0  (1) HookCode parameters changed -> only one flags parameter
    //          (2) (Un)InjectLibrary: user/session/system wide injection!
    //          (3) InjectLibrary2 replaced by InjectLibrary (auto detect)
    //          (4) static lib for Microsoft C++ added
    //          (5) CreateIpcQueue + SendIpcMessage + DestroyIpcQueue added
    //          (6) AmSystemProcess + AmUsingInputDesktop added
    //          (7) GetCurrentSessionId + GetInputSessionId added
    //          (8) GetCallingModule function added
    //          (9) ProcessIdToFileName added
    //          (a) Create/OpenGlobalMutex + Event + FileMapping added
    //          (b) WideToAnsi + AnsiToWide functions added
    //          (c) RenewHook function added
    //          (d) madCodeHook.dll -> madCHook.dll (8.3 dos name logic)
    //          (e) UnhookAPI added (= UnhookCode, added just for the look)
    //          (f) AddAccessForEveryone added
    // 2002-10-17 1.3f InjectLibrary2(W) was not stdcall (dumb me)
    // 2002-10-03 1.3e (1) InjectLibraryW added
    //          (2) InjectLibrary2(W) added for use in CreateProcess(W) hooks
    // 2002-09-22 1.3d CreateProcessExW added
    // 2002-03-24 1.3c CollectHooks/FlushHooks speed up mixture initialization
    // 2002-02-24 1.3b LPSTARTUPINFO -> LPSTARTUPINFOA
    // 2002-01-21 1.3a ProcessHandleToId exported
    // 2001-07-08 1.3  new functions (1) AllocMemEx & FreeMemEx
    //          (2) CopyFunction
    //          (3) CreateRemoteThread and
    //          (4) InjectLibrary added
    // 2001-04-20 1.2a you can now force HookCode/API to use the mixture mode
    // 2001-04-16 1.2  new function CreateProcessEx -> dll injecting

    unit madCHook;

    interface

    uses Windows;

    // **********

    type TPCardinal = ^cardinal;
         TPPointer  = ^pointer;

    // **********

    const
      // by default madCodeHook counts how many times any thread is currently
      // running inside of your callback function
      // this way unhooking can be safely synchronized to that counter
      // sometimes you don't need/want this counting to happen, e.g.
      // (1) if you don't plan to ever unhook, anyway
      // (2) if the counting performance drop is too high for your taste
      // (3) if you want to unhook from inside the hook callback function
      // in those cases you can set the flag "DONT_COUNT"
      DONT_COUNT = $00000001;

      // madCodeHook implements two different API hooking methods
      // the mixture mode is the second best method, it's only used if the main
      // hooking method doesn't work for whatever reason (e.g. API code structure)
      // normally madCodeHook chooses automatically which mode to use
      // you can force madCodeHook to use the mixture mode by specifying this flag:
      MIXTURE_MODE = $00000002;

      // under win9x you can hook code system wide, if it begins > $80000000
      // or if the code section of the to-be-hooked dll is shared
      // the callback function is in this case automatically copied to shared memory
      // use only kernel32 APIs in such a system wide hook callback function (!!)
      // if you want an easier way and/or a NT family compatible way to hook code
      // system wide, please use InjectLibrary(ALL_SESSIONS) instead of these flags:
      SYSTEM_WIDE_9X          = $00000004;
      ACCEPT_UNKNOWN_TARGETS_9X = $00000008;

    // hook any code or a specific API
    function HookCode (code         : pointer;
              callbackFunc : pointer;
              out nextHook : pointer;
              flags        : dword = 0) : longBool; stdcall;
             external 'madCHook.dll';
    function HookAPI (module, api  : pchar;
              callbackFunc : pointer;
              out nextHook : pointer;
              flags        : dword = 0) : longBool; stdcall;
             external 'madCHook.dll';

    // some firewall/antivirus programs kill our hooks, so we need to renew them
    function RenewHook (var nextHook: pointer) : longBool; stdcall;
             external 'madCHook.dll';

    // unhook again
    function UnhookCode (var nextHook: pointer) : longBool; stdcall;
             external 'madCHook.dll';
    function UnhookAPI (var nextHook: pointer) : longBool; stdcall;
             external 'madCHook.dll';

    // putting all your "HookCode/API" calls into a "CollectHooks".."FlushHooks"
    // frame can eventually speed up the installation of the hooks
    procedure CollectHooks; external 'madCHook.dll';
    procedure   FlushHooks; external 'madCHook.dll';

    // **********
    // same as CreateProcess
    // additionally the dll "loadLibrary" is injected into the newly created process
    // the dll is loaded right before the entry point of the exe module is called

    function CreateProcessEx  (applicationName, commandLine : pchar;
              processAttr, threadAttr      : PSecurityAttributes;
              inheritHandles          : longBool;
              creationFlags          : dword;
              environment          : pointer;
              currentDirectory          : pchar;
              const startupInfo          : TStartupInfo;
              var processInfo          : TProcessInformation;
              loadLibrary          : pchar          ) : longBool; stdcall;
             external 'madCHook.dll' name 'CreateProcessExA';
    function CreateProcessExW (applicationName, commandLine : pwidechar;
              processAttr, threadAttr      : PSecurityAttributes;
              inheritHandles          : longBool;
              creationFlags          : dword;
              environment          : pointer;
              currentDirectory          : pchar;
              const startupInfo          : TStartupInfo;
              var processInfo          : TProcessInformation;
              loadLibrary          : pwidechar          ) : longBool; stdcall;
             external 'madCHook.dll';

    // **********
    // memory allocation in the specified processes (shared memory in win9x)
    // if the processHandle is 0, the memory is allocated or freed in the shared
    // area (in win9x) or in our own process (in winNT)

    function AllocMemEx (size : dword;   processHandle : dword = 0) : pointer; stdcall; external 'madCHook.dll';
    function  FreeMemEx (mem  : pointer; processHandle : dword = 0) : bool;    stdcall; external 'madCHook.dll';

    // **********
    // copy (and relocate) any function to a new location in any process
    // if the processHandle is 0, the function is copied to shared area (in win9x)
    // or to another memory location in our own process (in winNT)
    // don't forget to free the function with FreeMemEx, if you don't it anymore

    function CopyFunction (func          : pointer;
              processHandle        : dword     = 0;
              acceptUnknownTargets : boolean   = false;
              buffer          : TPPointer = nil  ) : pointer; stdcall;
             external 'madCHook.dll';

    // **********
    // like CreateRemoteThread, but 3 changes:
    // (1) this one also works perfectly in win9x!!
    // (2) this one also works on other sessions in winNt
    // (3) the DACL of the current thread is copied in winNt (if threadAttr = nil)

    function CreateRemoteThreadEx (processHandle : dword;
              threadAttr    : PSecurityAttributes;
              stackSize     : integer;
              startAddr     : pointer;
              params        : pointer;
              creationFlags : dword;
              var threadId  : dword          ) : dword; stdcall;
             external 'madCHook.dll';

    // **********

    // this is how your remote function must look like
    type TRemoteExecuteFunction = function (params: pointer) : dword; stdcall;

    // executes the specified function in the context of another process
    // this works only if the function follows some specific rules
    // e.g. it must not use global variables, nor Delphi private functions
    // only win32 APIs are allowed
    // don't use Delphi strings, since they end up in local Delphi function calls
    // if "size" > 0, the "params" block will be copied to the other process
    // after the remote function is finished, the "params" block is copied back
    // so you can use the "params" block for both "in" and "out" parameters
    // if "size" = 0, the "params" value is just given into the remote function
    function RemoteExecute (processHandle  : dword;
              func          : TRemoteExecuteFunction;
              var funcResult : dword;
              params         : pointer = nil;
              size          : dword   = 0          ) : bool; stdcall;
             external 'madCHook.dll';

    // **********

    const
      // (un)inject the specified dll into (from) all current and future processes
      // these flags can be used for both UninjectLibrary + InjectLibrary
      ALL_SESSIONS     = $FFFFFFED;  // apps of all sessions
      CURRENT_SESSION  = $FFFFFFEC;  // apps of current session
      CURRENT_USER     = $FFFFFFEB;  // apps of current user

      // the following flags may only be used in combination with the first 3 flags
      SYSTEM_PROCESSES = $10;  // include this flag to include system processes + services
      CURRENT_PROCESS  = $08;  // exclude this flag to exclude injection into yourself

    // same as LoadLibrary, but this one is able to load the library into any process
    function InjectLibrary  (processHandle: dword; libFileName: pchar;     timeOut: dword = 7000) : bool; stdcall; external 'madCHook.dll' name 'InjectLibraryA';
    function InjectLibraryW (processHandle: dword; libFileName: pwidechar; timeOut: dword = 7000) : bool; stdcall; external 'madCHook.dll';

    // same as InjectLibrary(CURRENT_SESSION, ...), but you can choose the session
    function InjectLibrarySession  (session: dword; systemProcesses: bool; libFileName: pchar;     timeOut: dword = 7000) : bool; stdcall; external 'madCHook.dll' name 'InjectLibrarySessionA';
    function InjectLibrarySessionW (session: dword; systemProcesses: bool; libFileName: pwidechar; timeOut: dword = 7000) : bool; stdcall; external 'madCHook.dll';

    const
      // stop the "virus" injection effect (can be used for UninjectLibrary only)
      STOP_VIRUS = $FFFFFFFA;

    // same as FreeLibrary, but is able to free the library from any process
    function UninjectLibrary  (processHandle: dword; libFileName: pchar;     timeOut: dword = 7000) : bool; stdcall; external 'madCHook.dll' name 'UninjectLibraryA';
    function UninjectLibraryW (processHandle: dword; libFileName: pwidechar; timeOut: dword = 7000) : bool; stdcall; external 'madCHook.dll';

    // same as UninjectLibrary(CURRENT_SESSION, ...), but you can choose the session
    function UninjectLibrarySession  (session: dword; systemProcesses: bool; libFileName: pchar;     timeOut: dword = 7000) : bool; stdcall; external 'madCHook.dll' name 'UninjectLibrarySessionA';
    function UninjectLibrarySessionW (session: dword; systemProcesses: bool; libFileName: pwidechar; timeOut: dword = 7000) : bool; stdcall; external 'madCHook.dll';

    // **********

    // which processId belongs to the specified process handle?
    // undocumented function, works in all windows 32 bit systems
    function ProcessHandleToId (processHandle : dword) : dword; stdcall;
             external 'madCHook.dll';

    // find out what file the specified process was executed from
    // the file name buffer must have a size of MAX_PATH characters (or more)
    function ProcessIdToFileName (processId : dword;
              fileName  : pchar) : bool; stdcall;
             external 'madCHook.dll';

    // **********

    // is the current process a service/system process?  (win9x -> always false)
    function AmSystemProcess : bool; stdcall; external 'madCHook.dll';

    // is the current thread's desktop the input desktop?  (win9x -> always true)
    // only in that case you should show messages boxes or other GUI stuff
    // but please note that in XP fast user switching AmUsingInputDesktop may
    // return true, although the current session is currently not visible
    // XP fast user switching is implemented by using terminal server logic
    // so each fast user session has its own window station and input desktop
    function AmUsingInputDesktop : bool; stdcall; external 'madCHook.dll';

    // the following two functions can be used to get the session id of the
    // current session and of the input session
    // each terminal server (or XP fast user switching) session has its own id
    // the "input session" is the one currently shown on the physical screen
    function GetCurrentSessionId : dword; stdcall; external 'madCHook.dll';
    function GetInputSessionId   : dword; stdcall; external 'madCHook.dll';

    // **********

    // which module called me? works only if your function has a stack frame
    function GetCallingModule : dword; stdcall;
             external 'madCHook.dll';

    // **********
    // global  =  normal  +  "access for everyone"  +  "non session specific"

    function CreateGlobalMutex (name: pchar) : dword; stdcall; external 'madCHook.dll';
    function   OpenGlobalMutex (name: pchar) : dword; stdcall; external 'madCHook.dll';

    function CreateGlobalEvent (name: pchar; manual, initialState: bool) : dword; stdcall; external 'madCHook.dll';
    function   OpenGlobalEvent (name: pchar          ) : dword; stdcall; external 'madCHook.dll';

    function CreateGlobalFileMapping (name: pchar; size: dword) : dword; stdcall; external 'madCHook.dll';
    function   OpenGlobalFileMapping (name: pchar; write: bool) : dword; stdcall; external 'madCHook.dll';

    // **********

    // convert strings ansi <-> wide
    // the result buffer must have a size of MAX_PATH characters (or more)
    // please use these functions in nt wide API hook callback functions
    // because the OS' own functions seem to confuse nt in hook callback functions
    procedure AnsiToWide (ansi: pchar; wide: pwidechar); stdcall; external 'madCHook.dll';
    procedure WideToAnsi (wide: pwidechar; ansi: pchar); stdcall; external 'madCHook.dll';

    // **********
    // ipc (inter process communication) message services
    // in contrast to SendMessage the following functions don't crash NT services

    type
      // this is how you get notified about incoming ipc messages
      // you have to write a function which fits to this type definition
      // and then you give it into "CreateIpcQueue"
      // your callback function will then be called for each incoming message
      // CAUTION: each ipc message is handled by a seperate thread, as a result
      //          your callback will be called by a different thread each time
      TIpcCallback = procedure (name       : pchar;
              messageBuf : pointer;
              messageLen : dword;
              answerBuf  : pointer;
              answerLen  : dword); stdcall;

    // create an ipc queue
    // please choose a unique ipc name to avoid conflicts with other programs
    // only one ipc queue with the same name can be open at the same time
    // so if 2 programs try to create the same ipc queue, the second call will fail
    function CreateIpcQueue (ipc      : pchar;
              callback : TIpcCallback) : bool; stdcall;
             external 'madCHook.dll';

    // send an ipc message to whomever has created the ipc queue (doesn't matter)
    // if you only fill the first 3 parameters, SendIpcMessage returns at once
    // if you fill the next two parameters, too, SendIpcMessage will
    // wait for an answer of the ipc queue owner
    // you can further specify how long you're willing to wait for the answer
    // and whether you want SendIpcMessage to handle messages while waiting
    function SendIpcMessage(ipc          : pchar;
              messageBuf     : pointer;
              messageLen     : dword;
              answerBuf      : pointer = nil;
              answerLen      : dword   = 0;
              answerTimeOut  : dword   = INFINITE;
              handleMessages : bool    = true    ) : bool; stdcall;
             external 'madCHook.dll';

    // destroy the ipc queue again
    // when the queue owning process quits, the ipc queue is automatically deleted
    // only the queue owning process can destroy the queue
    function DestroyIpcQueue (ipc: pchar) : bool; stdcall;
             external 'madCHook.dll';

    // **********

    implementation

    uses madTools;

    initialization
      InitTryExceptFinally;
      IsMultiThread := true;
    end.

  • 相关阅读:
    Windows系统下安装运行Kafka
    Git强制拉取覆盖本地
    Windows Server 2008/2012 计划任务配置执行bat
    Task.Run()任务执行
    Oracle数据重复,只取一条
    Oracle数据库查看表空间是否为自增的
    How to disable Microsoft Compatibility Telemetry
    最新版谷歌浏览器的Flash设置已经不能保存了?
    亲子之间,在于看懂,无关耐心zz
    读懂孩子有方法
  • 原文地址:https://www.cnblogs.com/hnxxcxg/p/2940702.html
Copyright © 2011-2022 走看看