Page 2 of 3 FirstFirst 123 LastLast
Results 16 to 30 of 38

Thread: Hooking a member function from an injected DLL?

  1. #16
    Shakkan
    Guest
    Well, the solution must be compatible with XP x86/x64 and Vista x86/x64. :\
    PAGE_GUARD is too costy. As Admiral mentionned, guarding a full page would cause a big penalty performance since it's an executable file and there's a lot of chance that most nearby addresses get called very often.

    Anyone has a miraculous solution for me? Just to 'refresh' what I want to do: I need to be notified of when EIP passes through a certain address (i.e. 0x005C5600) during gameplay but I CANNOT modify the executable at all or PunkBuster will kill me. Also, I can't use hardware breakpoints because SafeDisc uses them all.

    Thanks again,
    Alex
    I promise that I have read the FAQ and tried to use the Search to answer my question.

  2. #17
    <script>alert(0)</script> disavowed's Avatar
    Join Date
    Apr 2002
    Posts
    1,281
    another option: how hard is it to "fix" punkbuster so that it won't be unhappy with software breakpoints in the target?

  3. #18
    Shakkan
    Guest
    Quote Originally Posted by disavowed View Post
    another option: how hard is it to "fix" punkbuster so that it won't be unhappy with software breakpoints in the target?
    I know it's a possible solution, but keep in mind that PunkBuster is a widely used software to prevent hacking. Even though my purpose is 100% legitimate, I'm no better than the cheaters in PB's eye (even if it's for one little INT3). PB is constantly updated and the software that I will distribute will be used by end users. Playing the cat & mouse game with PunkBuster really isn't my preferred choice. Imagine once PB releases a new version and the end users using my addon get kicked because of file/memory corruption. PB runs a md5 check on the whole executable in memory.

    But thanks for the suggestion. I'm running out of ideas here. Help!
    I promise that I have read the FAQ and tried to use the Search to answer my question.

  4. #19
    Your work is cut out for you, and there's really no easy fix. Both PunkBuster and SafeDisc are designed to stop exactly this kind of behaviour. You simply won't be able to fight much of a battle on both of these fronts without some serious reinforcements . I take it that assuming a power-role from kernel-mode is out of the question, right?
    www.ring3circus.com
    Diary of a programmer, journal of a hacker.

  5. #20
    Shakkan
    Guest
    Hi Admiral,

    That's great news! ...just kidding. heh
    Anyhow, I saw it coming, although I'm not giving up. Why do you assume that your proposition is out of the question? Can you resume briefly what is "assuming a power-role" from kernel-mode? I don't expect you to walk me through (I'm not that kinda guy :|), I will do my homework, but care to explain me the big idea?

    Thanks again!
    Alex
    I promise that I have read the FAQ and tried to use the Search to answer my question.

  6. #21
    Administrator dELTA's Avatar
    Join Date
    Oct 2000
    Location
    Ring -1
    Posts
    4,206
    Blog Entries
    5
    Shakkan, I think the kernel-mode suggestion is related to what Maximus mentioned earlier, which would as mentioned be of some trouble on Vista (due to PatchGuard).

    Btw, as a more general question, isn't there really some still currently working good way to disable PatchGuard on Vista? There has been many in the past, so I would suggest a google on "disabling PatchGuard" or "bypassing PatchGuard" for some possibly interesting information. Since the users of your software would most likely be willing to do whatever it takes to make it work on their computers, over which they have full administrative control, they would most likely be able to do this without any problems, no matter how roundabout the procedure might be.

    Maybe Alex would like to contribute some of his more than deep insight on this particular issue here? (for those not familiar with Alex's experiences in this field, see the following starting point for the whole PatchGuard circumvention hoopla: http://blogs.zdnet.com/security/?p=447 )

    Another Vista related thought: Now, if IDT patches and other miscellaneous trickery isn't possible on Vista for you, it shouldn't be possible for SafeDisc either, right? So, I would guess that the SafeDisc protection of the e.g. the debug registers etc isn't as fierce and hard to circumvent on Vista as on other operating systems then? Thus, you might be able to create two versions of your software (wrapped into the same program, with OS auto-detection for on-the-fly choice of which if you will). One kernel-driver based version for non-Vista OSs, and one non-kernel-driver based version for Vista, which might in turn not even require this in the first place to bypass this aspect of the SafeDisc protection, due to the reasons just mentioned?

    Anyone willing to share more info or counter arguments to this hypothesis?

    One more thing too: As far as I'm understanding this, you are only assuming that the PAGE_GUARD method would incur an unacceptable performance hit? This might not really always be the case, it depends completely on the layout of the code. If the adjacent code (i.e. the code in the same page as the interesting break address) is only rarely executed, it might very well work just great. I think you should implement this method and try it at least, since it will most likely be a working solution in at least some/many cases.
    "Give a man a quote from the FAQ, and he'll ignore it. Print the FAQ, shove it up his ass, kick him in the balls, DDoS his ass and kick/ban him, and the point usually gets through eventually."

  7. #22
    dELTA: Disabling Patchguard isn't a reliable solution, imho.

    Also, the DRs aren't really "protected" by Patchguard -- they're just reset during Patchguard's code paths.

    The solution Shakkan wants to be looking at is loading something in kernel-mode to use the DRs and patch out/ignore SafeDisc attempts to gobble them up.
    --
    Best regards,
    Alex Ionescu

  8. #23
    Administrator dELTA's Avatar
    Join Date
    Oct 2000
    Location
    Ring -1
    Posts
    4,206
    Blog Entries
    5
    Thanks for your insights Alex!

    Some clarification though:
    Quote Originally Posted by aionescu
    Also, the DRs aren't really "protected" by Patchguard -- they're just reset during Patchguard's code paths.
    Yes, what was discussed was rather the following "chained problem", where only PatchGuard is "indirectly" responsible for not allowing us to use the debug registers, by multiple layers of implication:
    1. PunkBuster is monitoring the target, and it is constructed in such a way that the only viable/practical method to acquire "breakpoint-like functionality" in games monitored by it is to use hardware breakpoints (well, or at least that's what the collected participants of this thread seems to be able to conclude anyway, including myself).
    2. SafeDisc is protecting the target, and it is constructed in such a way that it uses assorted trickery (including ring 0 such) in order to prevent you from making use of any of the debug registers, and thus also implicitly preventing you from using any hardware breakpoints on the target.
    3. The method that has been suggested to neutralize this show-stopper feature of SafeDisc is to subvert it by means of miscellaneous kernel-level hooks (remember that we cannot remove or patch the SafeDisc protection directly, since this would make PunkBuster unhappy and bring us back to square one, where it has already been concluded that attempting to neutralize PunkBuster itself is not a viable option ).
    4. The working hypothesis is then that the implementation of such effective hooks can only be acquired by means of IDT patching or similar.
    5. The next assumption is that "IDT patching or similar" will always be prevented on Windows Vista by the PatchGuard feature of the operating system, which will thus, implicitly, prevent this angle of attack in its entirety.
    6. The next logical step to be concluded was to neutralize PatchGuard, in order to unwind this annoying chain of interdependent show-stopping details, and thus be able to reach our initial goal by means of making SafeDisc allow us to use hardware breakpoints without actually patching it directly.
    I'm not a ring 0 guru at all, so the hypotheses and assumptions listed above might very well be false at some places, which would indeed just make me happy. In that case it would be great if someone more knowledgeable could step up and let us know. Alternatively, if someone with deeper knowledge of SafeDisc would know of a good way to neutralize its hardware breakpoint meddling without either patching the memory areas affected by the PunkBuster checksums, or using "IDT patching or similar" that will be stopped by PatchGuard, that would be a great possible solution too.


    Quote Originally Posted by aionescu
    The solution Shakkan wants to be looking at is loading something in kernel-mode to use the DRs and patch out/ignore SafeDisc attempts to gobble them up.
    Considering my explanation of the problem above, do you still think this is a viable/possible option? In that case, with just a few words to push people in the right direction, how?


    Quote Originally Posted by aionescu
    Disabling Patchguard isn't a reliable solution, imho
    The problem at hand seems likely to force us to settle with "the least unreliable solution" rather than "a reliable solution", which is why I went down this path to begin with. When you say that it isn't reliable, do you mean it in a "it's-a-too-ugly-hack-although-working" way, or in a "there-are-strictly-technically-no-known-ways-what-so-ever-to-disable-PatchGuard-today" way? Also, remember that the persons who would like to do this have total (including physical) control of their computers.

    If nothing else, I really think it should be possible to do such a thing by either making use of a direct kernel memory patch with a modified version of the firewire DMA vulnerability Windows login bypass exploit (http://storm.net.nz/projects/16), or by making use of an pre-boot rootkit, like e.g. the BootRoot boot sector rootkit that eEye makes available with source code and everything (http://research.eeye.com/html/tools/RT20060801-7.html ... hmm, server not available at the moment, here is the Google cache anyway (remove linebreak in URL): http://64.233.183.104/search?q=cache:NGXyna1aMscJ:research.eeye.com/html/tools/RT20060801-7.html+
    eeye+bootroot&ct=clnk&cd=1
    ), and which has also already been used to create apparently quite stable malware code in the wild (http://www.woodmann.com/forum/showthread.php?t=11370). Maybe that's a project that someone around here would think was a fun and worthy challenge?

    These last two suggestions are of course quite extreme measures, but I like to conquer all problems and limitations, no matter the means necessary, and I can only assume the same about game hackers.
    "Give a man a quote from the FAQ, and he'll ignore it. Print the FAQ, shove it up his ass, kick him in the balls, DDoS his ass and kick/ban him, and the point usually gets through eventually."

  9. #24
    mmh... I never faced punkbuster (...doing other things), but for what I've read, it uses DR0/3 with values, or at least it monitors them.

    Rethinking, Vista won't allow PB to thunk INT1, so probably this is true on XP too.
    This means that DR registers can be used in 2 ways. They can keep "Data" or "R3/R0 Transition Switch". Supposing that PB guys do not unsafely jump back and forth the Privilege Machine using hardware breakpoints and some hook (which would be very lame, unsafe and not very original), DR registers can only contain data used by PB.

    This brings to the following:
    * IF they are only used at R3, hook Get/SetThreadContext, KiUserDispatchException and you are done.
    * on R0... mmh... It depends on the way they do the R3/R0 transitions. Doers the R3 application accesses R0 normally? (i.e. not rogue INT1, direct calls to strange INTs, hooked SSDT etc.) However, it *might* be possible to code a Filter Driver for PunkBuster, that restore/save whatever you need. This would make it fully compatible in Vista, too. Just take some simple filter driver code, hook all IRP_MJ used by PB and make them restore the states you need, then set a completion routine that set your needed stuff back as you wanted. Witha bit of luck, it may suffice.
    Last edited by Maximus; March 22nd, 2008 at 20:13.
    I want to know God's thoughts ...the rest are details.
    (A. Einstein)
    --------
    ..."a shellcode is a command you do at the linux shell"...

  10. #25
    Shakkan
    Guest
    Hello guys,

    I just want to let you know I REALLY appreciate all your inputs on this subject. Extremely constructive. I can't keep up with the thread right now as I am busy with guests, but I will as soon as tomorrow and get back to you. I got some reading to do.

    Thank you!
    P.S.: Sorry for the useless post. I just wanted to make a quick one to let you know I am still following the thread (I've been checking for possible replies every few hours
    I promise that I have read the FAQ and tried to use the Search to answer my question.

  11. #26
    Since the link is down, I'm attaching the eEye "BootRoot boot sector rootkit" that dELTA mentioned.

    Regards,
    Attached Files Attached Files
    JMI

  12. #27
    xtc
    Guest
    Thought I'd make a minor correction, given the subject title...
    You're correct that member pointers cannot be cast to and from.
    However pointers to member pointers are not similarly restricted.
    I've written a demonstration, similar to what you were trying to accomplish:
    Code:
    #include <iostream>
    
    class Test {
    public:
        typedef void (Test::*MemberPfn)(void);
    
        void Target(void) {
            std::cout << "Test::Target()" << std::endl;
        }
    };
    
    class MyTest {
        typedef void (MyTest::*MemberPfn)(void);
        static MemberPfn m_targetPtr;
    
    public:
        static void* GetHook() {
            static MemberPfn pfn = &MyTest::Hook;
            return *(void**)&pfn;
        }
        static void SetTarget(void* ptr) {
            *(void**)&MyTest::m_targetPtr = ptr;
        }
    
        void Hook(void) {
            std::cout << "MyTest::Hook()" << std::endl;
    
            if (this->m_targetPtr) {
                (this->*m_targetPtr)();
            }
        }
    };
    MyTest::MemberPfn MyTest::m_targetPtr = 0;
    
    int main(int argc, char* argv[])
    {
        Test::MemberPfn targetPtr = &Test::Target;
        MyTest::SetTarget(*(void**)&targetPtr);
    
        *(void**)&targetPtr = MyTest::GetHook();
    
        Test* test = new Test();
        (test->*targetPtr)();
        delete test;
    
        return 0;
    }

    Your second problem seems twofold:
    • 1) SafeDisc is messing with the debug registers.
      Have you considered determining the nature of this usage?
      Where are they used? How are they used? Could the usage be circumvented/simulated?
      The DRx accessing/mutating code is located in SafeDisc's driver.
      Usermode applications and drivers have a limited number of ways of communicating with each other, the most common of which is the request/response model of DeviceIoControl. Here's a conceptual summary of the process:
      • The application opens a symbolic link (CreateFile) to a device of the driver in question. Prepares a request in the form of a device specific io control code and optionally data required to cary out the request. The request is sent to the driver using DeviceIoControl.

      • The driver receives the request through a callback function (IRP_MJ_DEVICE_CONTROL) specified in it's DRIVER_OBJECT. The callback is passed an io request packet (IRP) which contains the request information. The callback will then carry out the request and as a response return a) a status code indicating if the request was successful or not and optionally b) data generated as part of the request.

      • The os will then perform a number of tasks depending on the situation. If the callback returned an error status code, it will convert it to a usermode error code and set that in the last error variable. If data was provided as part of the response, it will be copied to the output buffer specified in the DeviceIoControl call. And finally it will return from the DeviceIoControl call.

      Given this model, what options do you have for isolating "malicious" requests to the driver?


    • 2) You've got punkbuster watching over your shoulders.
      Any solution that you can come up with for trapping execution within executable images monitored by pb, will be of interest to pb, whether it currently detects it or not.

      From Ring 3 it seems you have little options but to somehow circumvent pb. This obviously requires a familiarisation with the inner workings of pb.
      I'd suggest heading over to http://forum.gamedeception.net for more information about pb.

      For Ring 0 you've got a few more options, however knowledge of driver development is required.
      Assuming that pb does check the debug registers, you'd have to hide them. This could be done by hooking the kernel level apis responsible of carrying out Get/SetThreadContext's doing. Or if pb is accessing them directly, by using the global detect flag to trap such access.
      "Raising The Bar For Windows Rootkit Detection" (http://www.phrack.org/issues.html?issue=63&id=8#article) outlines a method for hiding executable code which is designed to solve your specific type of problem. However, I'm not sure if this approach can be applied/adapted to Vista or x86-64 (I'm clueless about both).
      These are the only immutable methods of trapping execution that I know of, that is, debug registers and page table modification.


    What it ultimately comes down to, I think, is a choice between learning driver development or researching punk buster.
    I promise that I have read the FAQ and tried to use the Search to answer my question.

  13. #28
    Administrator dELTA's Avatar
    Join Date
    Oct 2000
    Location
    Ring -1
    Posts
    4,206
    Blog Entries
    5
    Very nice insights Maximus and xtc!

    I'm a little bit confused over one previous thing that is made current here, and just want to clear it up:

    Quote Originally Posted by Shakkan
    It does work just fine now _without_ SafeDisc. I have the SEH catch the exception triggered by the hardware breakpoint, enable single-step mode and disable the hardware breakpoint. Then I have a VEH catching the single-step exception, disabling single-step mode and enabling hardware breakpoint back.

    When used with a SafeDisc-enabled exe, the application freezes as soon as a breakpoint is hit.
    Shakkan, please confirm that I'm right in assuming that PunkBuster will never allow an un-SafeDisced exe to begin with, correct? And that means that you performed this test without PunkBuster being active, in a non-live situation (thus, still useless for your purposes), correct?

    Otherwise it really seems that the easiest solution would just be to use an un-SafeDisced version of the exe when performing whatever stuff it is that you're doing? But again, it seems very strange that PunkBuster would allow the un-SafeDisced exe to begin with?


    Quote Originally Posted by Maximus View Post
    mmh... I never faced punkbuster (...doing other things), but for what I've read, it uses DR0/3 with values, or at least it monitors them.
    This quote is what made me think about this unclarity to begin with, since it would be proven false by Shakkan's statement above if PunkBuster was running at the time of the described test. If the answer to my question above (i.e. if the successful test with the un-SafeDisced exe was performed with PunkBuster active) is yes, then I guess this cannot be true (i.e. that PunkBuster monitors DR registers)? But once more again, I really don't think that PunkBuster would allow an un-SafeDisced exe to begin with, right?


    Quote Originally Posted by Maximus View Post
    Rethinking, Vista won't allow PB to thunk INT1, so probably this is true on XP too.
    Yes, this is the line of thought I was having above too, only that I wasn't a big enough ring 0 buff to deduce the rest of the details that you concluded, but rather only the same end result on a very conceptual level.


    And xtc, the SafeDisc driver communication subversion suggestion is exactly the kind of thing I had in mind with the following, thanks!
    Quote Originally Posted by dELTA
    Alternatively, if someone with deeper knowledge of SafeDisc would know of a good way to neutralize its hardware breakpoint meddling without either patching the memory areas affected by the PunkBuster checksums, or using "IDT patching or similar" that will be stopped by PatchGuard, that would be a great possible solution too.
    "Give a man a quote from the FAQ, and he'll ignore it. Print the FAQ, shove it up his ass, kick him in the balls, DDoS his ass and kick/ban him, and the point usually gets through eventually."

  14. #29
    Shakkan
    Guest

    Thumbs up

    Quote Originally Posted by dELTA
    One more thing too: As far as I'm understanding this, you are only assuming that the PAGE_GUARD method would incur an unacceptable performance hit? This might not really always be the case, it depends completely on the layout of the code. If the adjacent code (i.e. the code in the same page as the interesting break address) is only rarely executed, it might very well work just great. I think you should implement this method and try it at least, since it will most likely be a working solution in at least some/many cases.
    You are right. I am assuming, but the address I want to monitor is part of a code segment (not data) so it's highly likely that adjacent instructions get called very often. Yet, I admit that I should try it to validate or invalidate what I assume. PAGE_GUARD also works with code segments, not just data segments, right?

    Quote Originally Posted by Maximus
    * IF they are only used at R3, hook Get/SetThreadContext, KiUserDispatchException and you are done.
    Unfortunately, it's used at a lower level. DeviceIoControl is used by SafeDisc for DR manipulation. :\

    Quote Originally Posted by xtc
    Usermode applications and drivers have a limited number of ways of communicating with each other, the most common of which is the request/response model of DeviceIoControl.
    That's right. SafeDisc DOES use DeviceIoControl to play with the debug registers. I did a bit of research and some guy who disassembled SafeDisc code could locate the calls to DeviceIoControl.

    Thank you for the explanation and distinction on member pointers and pointers to member pointers. However, my initial issue was to hook a member function to which the only thing I got is a bare address (no code to do a &Class::Method). Fortunately, I previously found a solution to this (the code involves converting a _thiscall to _stdcall by pushing ECX to the stack and put a void* as first parameter on the hook function declaration). PunkBuster made this all pointless though, but still interesting to know.

    Quote Originally Posted by dELTA
    Shakkan, please confirm that I'm right in assuming that PunkBuster will never allow an un-SafeDisced exe to begin with, correct? And that means that you performed this test without PunkBuster being active, in a non-live situation (thus, still useless for your purposes), correct?
    I can confirm it. An un-SafeDisc'd version of the executable would result on a different md5 when PB decides to do a routine exe scan.

    Quote Originally Posted by dELTA
    This quote is what made me think about this unclarity to begin with, since it would be proven false by Shakkan's statement above if PunkBuster was running at the time of the described test. If the answer to my question above (i.e. if the successful test with the un-SafeDisced exe was performed with PunkBuster active) is yes, then I guess this cannot be true (i.e. that PunkBuster monitors DR registers)? But once more again, I really don't think that PunkBuster would allow an un-SafeDisced exe to begin with, right?
    Well, I am to blame for this. Sorry.
    I know for a fact that SafeDisc uses the DR but I didn't try my code (hardware bp + SEH) with an un-SafeDisc'd executable online where PunkBuster is active. Since PB does not compute a md5 every second on the executable, I CAN test an un-SafeDisc'd version online quick and see if PunkBuster is a culprit too. I will try that too on Tuesday to get more info.

    To everyone:
    Obviously, you guys are way above my league. IDT patching, driver development knowledge, PatchGuard, all around Ring 0 knowledge. I will continue reading the links that were posted here but anyone knows some good resources (ebooks, articles, etc.) about basic information on R0/R3/IDT patching/etc. (i.e. the kind of stuff you expect me to know so I can follow you) so I can educate myself further and further? Please don't throw in the towel, I'm loving the contribution by this community. I will do my homework and won't give up.
    I promise that I have read the FAQ and tried to use the Search to answer my question.

  15. #30
    Administrator dELTA's Avatar
    Join Date
    Oct 2000
    Location
    Ring -1
    Posts
    4,206
    Blog Entries
    5
    One important conclusion here is that if PunkBuster uses the debug registers itself, neutralizing SafeDisc in a not-by-PunkBuster detectable way still won't have accomplished anything, and then you're back again to the two remaining options of trying the PAGE_GUARD method (which I guess might very well be detectable by PunkBuster too?) or going after PunkBuster directly.

    I suggest that you verify this before putting any large amounts of work into attacking SafeDisc.

    Again regarding the PAGE_GUARD assumptions, yes, it can be done on code, and no, 4096 bytes of code really isn't that much at all in a big game executable, so if you're lucky, none of that code is executed very often, which might lead to acceptably low levels of performance loss. I'd say that currently, everything points in the direction of trying out this method, before doing anything else.
    "Give a man a quote from the FAQ, and he'll ignore it. Print the FAQ, shove it up his ass, kick him in the balls, DDoS his ass and kick/ban him, and the point usually gets through eventually."

Similar Threads

  1. Replies: 2
    Last Post: September 4th, 2011, 06:07
  2. Call a dll injected function from the host process
    By Smjert in forum The Newbie Forum
    Replies: 13
    Last Post: June 17th, 2010, 19:05
  3. Replies: 3
    Last Post: February 9th, 2008, 14:30
  4. Replies: 0
    Last Post: December 5th, 2007, 16:45
  5. sXe injected
    By syl in forum The Newbie Forum
    Replies: 5
    Last Post: May 9th, 2007, 16:43

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •