none
Unable to detour a native application whilest being able to detour a managed one. RRS feed

  • Question

  • Hi,

    I'm trying to detour the function "gethostbyname" residing in the winsock2 libraries and I'm having problems with Reading and Writing process memory. Here is my code:

    [UnmanagedFunctionPointer(CallingConvention.Winapi)]
        public delegate IntPtr GetHostByNameDelegate(IntPtr name);
    [DllImport("kernel32.dll", SetLastError=true)]
      static extern bool ReadProcessMemory(
      IntPtr hProcess, 
      IntPtr lpBaseAddress,
      IntPtr lpBuffer, 
      int dwSize, 
      out int lpNumberOfBytesRead
      );
        [DllImport("kernel32.dll", SetLastError = true), SuppressUnmanagedCodeSecurity]
        internal static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize,
                                out int lpNumberOfBytesWritten);
        [DllImport("kernel32", CharSet = CharSet.Ansi), SuppressUnmanagedCodeSecurity]
        internal static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
    
        [DllImport("kernel32.dll"), SuppressUnmanagedCodeSecurity]
        internal static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, int dwProcessId);
    
        [DllImport("kernel32"), SuppressUnmanagedCodeSecurity]
        internal static extern IntPtr LoadLibrary(string libraryName);
        static GetHostByNameDelegate GetHostByNameHandler = GetHostByName;
    
        static List<byte> original = new List<byte>();
    
        static List<byte> _new = new List<byte> { 0x68 };
    
    static void Main()
    {
    IntPtr handle = IntPtr.Zero;
          foreach (Process p in Process.GetProcesses())
          {
            if (p.ProcessName.Contains("DemoNativeApp"))
            {
              handle = OpenProcess(0x0010 | 0x0020 | 0x0008, false, p.Id);
            }
          }
          Console.WriteLine(handle);
          IntPtr lib = LoadLibrary("WSOCK32.dll");
          IntPtr addr = GetProcAddress(lib, "gethostbyname");
          GetHostByNameDelegate orig_addr = (GetHostByNameDelegate)Marshal.GetDelegateForFunctionPointer(addr, typeof(GetHostByNameDelegate));
          IntPtr _original = Marshal.AllocHGlobal(6);
          byte[] _boriginal = new byte[6];
          int BytesRead = 0;
          ReadProcessMemory(handle, addr, _original, 6, out BytesRead);
          Console.WriteLine(Marshal.GetLastWin32Error());
          Marshal.Copy(_original, _boriginal, 0, 6);
          original.AddRange(_boriginal);
          _new.AddRange(BitConverter.GetBytes(Marshal.GetFunctionPointerForDelegate(GetHostByNameHandler).ToInt32()));
          _new.Add(0xC3);
          WriteProcessMemory(handle, addr, _new.ToArray(), (uint)_new.Count, out BytesRead);
    
          Console.WriteLine(Marshal.GetLastWin32Error());
          Console.ReadLine();
    }

    ReadProcessMemory returns error 299 and WriteProcessMemory returns error 487. I'm just not understanding the problem because it works fine on another managed application.

    Thanks.

    Sunday, July 4, 2010 12:09 AM

Answers

  • Whoha! You can't just take a pointer from your process and use it to read some memory from another process!!! There is absolutelty no guarantee the function will be sitting at the same adress! or even that it has the library loaded! I suggest you let a proper written library do the heavy lifting for you like EasyHook .  Or even better do your hooking in native code, with perhaps detours given its alot nicer on the system resources
    • Marked as answer by Illusha Monday, July 5, 2010 1:05 PM
    Sunday, July 4, 2010 1:43 AM

All replies

  • Whoha! You can't just take a pointer from your process and use it to read some memory from another process!!! There is absolutelty no guarantee the function will be sitting at the same adress! or even that it has the library loaded! I suggest you let a proper written library do the heavy lifting for you like EasyHook .  Or even better do your hooking in native code, with perhaps detours given its alot nicer on the system resources
    • Marked as answer by Illusha Monday, July 5, 2010 1:05 PM
    Sunday, July 4, 2010 1:43 AM
  • Thanks very much for your reply, I will try using another library. However, would it be possible to somehow find the library's location in the other application using something like GetProcAddress?
    Monday, July 5, 2010 1:06 PM
  • Kinda feel like i'm repeating my self but, No GetProcAddress will return the address of the function in *your* process, there's no guarantee that the function will be sitting at the same adress in another process there's no guarantee the other process even has the library loaded. The lesson you should learn is : A pointer from process X is worthless in process Y you can never ever ever mix and match pointers from different processes.  You might have lucked out with a process or two but given Address Space Layout Randomization (wikipedia link) slowly getting more accepted those odds will only go down. 

    Not trying to be mean here but with such a poor understanding of the Operating system architecture should you really be hooking stuff? The odds of understanding the implications of your actions (for instance mapping a 35mb CLR into each and every process you invade when you use managed hooking, or the complete disaster that will occur if the process already has a different version if the clr loaded) seem to be very low which will probably end up in an unstable application or a monster that will abuse system resources like there is no tomorrow, neither is very good for your end users.

     

    Monday, July 5, 2010 1:30 PM
  • Then how do you suggest I go about hooking this process? I do not want to use any 3rd party applications to help me, I'd rather start from scrath.
    Monday, July 5, 2010 2:11 PM
  • I suggest you don't.
    Monday, July 5, 2010 3:48 PM