+ Reply to Thread
Page 1 of 3 1 2 3 LastLast
Results 1 to 15 of 31

  Click here to go to the first staff post in this thread.   Thread: Import masking library

  1. #1
    Join Date
    May 2009
    Posts
    405
    Thanks
    3
    Thanked 7 Times in 5 Posts
    Blog Entries
    1
    Rep Power
    37

    Import masking library

    After many rewrites and varying looks at how the library functions, I've finally decided I need to scrap the original design and redesign it entirely, for it was too volatile and unstable.

    Download: http://www.sendspace.com/file/fqk4ge

    Everything in the main.cpp source file is just demonstrating how the library can be used; the library functions itself are stored in fxn.cpp and fxn.h.

    Good luck everyone

    Introducing my own little API redirection-type library!

    Code:
    #include "fxn.h"
    
    int main()
    {
    	fxn i;
    
    	try
    	{
    		i.SetFunction("user32.dll", HASH("MessageBoxA"));
    		i.Call(NULL, "Hi", "ANSI (MessageBoxA)", MB_OK);
    
    		i.SetFunction("user32.dll", HASH("MessageBoxW"));
    		i.Call(NULL, L"Hi", L"Unicode (MessageBoxW)", MB_OK);
    	}
    	catch(std::runtime_error& e)
    	{
    		std::cout << e.what() << std::endl;
    		std::cin.ignore();
    	}
    	return (0);
    }
    You specify the name of the library to import from, then the function name (Requesting it be hashed using the compile-time hash macro, HASH), then call it with all needed parameters.

    The library will first attempt to locate the library in memory (Using a custom GetModuleHandle rewrite), then it'll call LoadLibrary to load it manually (LoadLibrary being hidden in the imports, of course).

    The get procedure address function (Rewrite of GetProcAddress) does not support forwarded functions, sorry, it's just a feature I consider unnecessary.

    Imports are located in the export table of the module in memory; as an extra little trick, if any NOP's are located before the function, the call is offsetted by X number of NOP's, making none of the addresses being called resolve to anything in the EAT of the DLLs.

    I don't use return-code logic for error checking, I use C++ exceptions (try/catch); you could change that yourself if you want, nothing I wrote is terribly C++ specific (Classes, use of reinterpret cast, command line IO, and C++ exceptions are about it).

    One other security benefit: a hash for the requested function to be imported is handed off, not the raw string; you never actually see the raw string in memory or on disk, making import recovery that much more of a pain in the ass.

    Diagram explaining what SetFunction does:


    Have fun!

    UPDATE:

    - The address to the function stored is now encrypted.
    - Updated compile-time string hashing; strings up to a length of 32 characters are supported now.

    It's recommended that you change the hash seed, the number being used for creating the checksum:

    Code:
    static const unsigned short hash_seed = 0x6281;
    To a different number when using this library. Also, there's an identifiable fingerprint with each throw clause, which, outside of debugging, I recommend be changed for this reason. Maybe remove the throwing of strings, and just have a custom error code be thrown instead, which users may report back to the original developers, should they receive some sort of error or crash when using a program that utilizes this library.

    I forgot to add, the library supports three compilers right now: GCC, MSVC, and ICC. The only compiler-specific item that the library uses is inline assembly for reading the FS/GS register; for MSVC, I use intrinsics to do so (Giving the library x86_64 compatibility), and for GCC/ICC, I use rewrites of said intrinsic functions using inline assembly.

    I forgot to add a special thanks to NTInternals.net for their documenting of undocumented structures, such as the PEB, which I used in my GetModuleHandle rewrite.

    Download: http://www.sendspace.com/file/25cb4e
    Last edited by Guy; 02-12-2010 at 03:13 PM.

  2. #2
    Join Date
    Jun 2004
    Location
    The Moon
    Posts
    2,977
    Thanks
    0
    Thanked 63 Times in 40 Posts
    Rep Power
    192

    Re: Import masking library

    it would be more of pita if you encrypted the returned address and it would prevent tools from using a lookup of commonly imported kernel32 addresses to find any code injection

    ([oC]Streetmedic): wav hate my guts
    ([oC]Streetmedic): i swear he shadowz me
    (Absolution): its true
    (Absolution): actually
    P47R!CK says:
    you are no good for me
    [gØt]wäv? says:
    wrong
    i am good for you
    [gØt]wäv? says:
    and you know it

  3. #3
    Join Date
    May 2009
    Posts
    405
    Thanks
    3
    Thanked 7 Times in 5 Posts
    Blog Entries
    1
    Rep Power
    37

    Re: Import masking library

    I actually considered that, maybe using EncodePointer, like I did before, along with a custom encryption scheme. Either way, that's extremely easy to do with my setup, so anyone who wants to do it should be able to.

  4. #4
    Join Date
    Jan 2007
    Location
    127.0.0.1
    Posts
    522
    Thanks
    1
    Thanked 7 Times in 7 Posts
    Rep Power
    72

    Re: Import masking library

    The only issue I see so far with this is that you are still relying on LoadLibrary to load a lib thats not found. A user can hook it and alter the call as they see fit. Such as with your example program calling MessageBoxA/MessageBoxW, monitoring for LoadLibraryA with user32.dll you can still get your own calls to happen. Granted you wont have the call information as to why the dll is being loaded for what function unless you do more work to get that info, but a simple detour works fine:

    PHP Code:
    HMODULE WINAPI Mine_LoadLibraryALPCSTR lpFileName )
    {
        if( 
    lpFileName && ( _stricmplpFileName"user32.dll" ) == ) )
        {
            return 
    Real_LoadLibraryA"somehack.dll" );
        }
        return 
    Real_LoadLibraryAlpFileName );

    somehack.dll then just exports new MessageBoxA/MessageBoxW calls such as:

    PHP Code:
    int __declspecdllexport WINAPI mine_MessageBoxW__in_opt HWND hWnd__in_opt LPCWSTR lpText__in_opt LPCWSTR lpCaption__in UINT uType )
    {
        
    OutputDebugString
            
    _T"Hooked MessageBoxW called." )
            );
        return 
    1;
    }

    int __declspecdllexport WINAPI mine_MessageBoxA__in_opt HWND hWnd__in_opt LPCSTR lpText__in_opt LPCSTR lpCaption__in UINT uType )
    {
        
    OutputDebugString
            
    _T"Hooked MessageBoxA called." )
            );
        return 
    1;

    export.def:
    PHP Code:
    LIBRARY    "somehack"
    EXPORTS
        MessageBoxW 
    mine_MessageBoxW
        MessageBoxA 
    mine_MessageBoxA 
    Proof of concept just to see if I could get past it, works fine. Not really the best method of this since it will fail to call any other function from the dll, so in theory you'd have to proxy every function doing something this way.
    patchLib: (A GDI Gui Library) Click here!
    FontFactory v2: (D3D8 Font Renderin Library) Click here!
    Personal Development Blog: Click here!

    (20:59:23) (%BadHAL) fine i will use vb

  5. #5
    Join Date
    May 2009
    Posts
    405
    Thanks
    3
    Thanked 7 Times in 5 Posts
    Blog Entries
    1
    Rep Power
    37

    Re: Import masking library

    At some level, that's always going to be possible; if I rewrite LoadLibraryA, I'll have to rely on file IO, and then what? I could have the DLL's in the IAT structure of the executable, importing nothing, but then anyone can just suspend all threads during initialization and replace the pathname of the specified DLL.

    Of course this is evadable; that's why you have checksums on the functions you import, to some extent. Maybe check if all loaded DLL's are signed and authentic or not.

    Updated main post.

  6. #6
    Join Date
    Jun 2004
    Location
    The Moon
    Posts
    2,977
    Thanks
    0
    Thanked 63 Times in 40 Posts
    Rep Power
    192

    Re: Import masking library

    Quote Originally Posted by Guy View Post
    I actually considered that, maybe using EncodePointer, like I did before, along with a custom encryption scheme. Either way, that's extremely easy to do with my setup, so anyone who wants to do it should be able to.
    wat

    encodepointer/decodepointer = slointer aka wat u do about dose?

    ps thx to loopens for trollens

    ([oC]Streetmedic): wav hate my guts
    ([oC]Streetmedic): i swear he shadowz me
    (Absolution): its true
    (Absolution): actually
    P47R!CK says:
    you are no good for me
    [gØt]wäv? says:
    wrong
    i am good for you
    [gØt]wäv? says:
    and you know it

  7. #7
    Join Date
    May 2009
    Posts
    405
    Thanks
    3
    Thanked 7 Times in 5 Posts
    Blog Entries
    1
    Rep Power
    37
    Yes, they're a bit slow, but they're secure. You could always use EncodeSystemPointer/DecodeSystemPointer if you prefer speed, or just use a custom algorithm all together, which is sort-of what I've done for the time being (As of the last update).

  8. #8
    Join Date
    May 2009
    Posts
    405
    Thanks
    3
    Thanked 7 Times in 5 Posts
    Blog Entries
    1
    Rep Power
    37
    Update: For some reason, the application would randomly crash for specific functions (e.g. Sleep from kernel32.dll); once I removed it from the class, it worked fine. It's protected now with my own implementation of "critical sections", but, now you're limited to using this one call at a time. I'll think up a better solution later, maybe using TLS for a multi-threaded solution.

    http://www.sendspace.com/file/e3s1g0

  9. #9
    Join Date
    May 2009
    Posts
    405
    Thanks
    3
    Thanked 7 Times in 5 Posts
    Blog Entries
    1
    Rep Power
    37
    (Hopefully) last update: http://www.sendspace.com/file/bf70kc

    I kept experiencing problems using the Call cast, so, rather than using a different cast each time, I'm having you, the user, be the one to make the call. Usage is like so:

    Code:
    typedef LONG(WINAPI *nqit_t)(HANDLE, LONG, PVOID, ULONG, PULONG);
    
    nqit_t NtQueryInformationThread = (nqit_t) fxn::GetFunction("ntdll.dll", HASH("NtQueryInformationThread"));
    You'll need a function cast/type definition for all your functions now, I know that's annoying, but that's the safest, least volatile way of doing things.

    Good luck everyone

  10. #10
    Join Date
    Sep 2006
    Posts
    636
    Thanks
    21
    Thanked 12 Times in 12 Posts
    Rep Power
    72

    Re: Import masking library

    tbh i prefer solutions that are drop-in and don't require rewriting entire code :/

    you could make this into a .lib that you can use in your project, excluding kernel32 and user32 lib's?
    - "Double the gun, double the fun!"

  11. #11
    Join Date
    May 2009
    Posts
    405
    Thanks
    3
    Thanked 7 Times in 5 Posts
    Blog Entries
    1
    Rep Power
    37

    Re: Import masking library

    Quote Originally Posted by learn_more View Post
    tbh i prefer solutions that are drop-in and don't require rewriting entire code :/

    you could make this into a .lib that you can use in your project, excluding kernel32 and user32 lib's?
    Yes, however, imports for hundreds of functions would be in memory, which would simply slow everything down.

    Plus, then you need a way to initialize the lookup function for each and every function.

    But, anyone who wants to do such a thing, feel free.

  12. #12
    Join Date
    Jun 2004
    Location
    The Moon
    Posts
    2,977
    Thanks
    0
    Thanked 63 Times in 40 Posts
    Rep Power
    192

    Re: Import masking library

    Quote Originally Posted by learn_more View Post
    tbh i prefer solutions that are drop-in and don't require rewriting entire code :/

    you could make this into a .lib that you can use in your project, excluding kernel32 and user32 lib's?
    the solution guy wrote is for a reason, so there is no iat generated in the .dll

    ([oC]Streetmedic): wav hate my guts
    ([oC]Streetmedic): i swear he shadowz me
    (Absolution): its true
    (Absolution): actually
    P47R!CK says:
    you are no good for me
    [gØt]wäv? says:
    wrong
    i am good for you
    [gØt]wäv? says:
    and you know it

  13. #13
    Join Date
    Aug 2004
    Location
    c:\tmp\~8b045cf75687.tmp
    Posts
    471
    Thanks
    7
    Thanked 6 Times in 4 Posts
    Rep Power
    84

    Re: Import masking library

    Very nice. Icing on the cake would be mashing the address in some way ... maybe storing it as two numbers which added together are the correct address ...

  14. #14
    Join Date
    Sep 2006
    Posts
    636
    Thanks
    21
    Thanked 12 Times in 12 Posts
    Rep Power
    72

    Re: Import masking library

    Quote Originally Posted by Guy View Post
    Yes, however, imports for hundreds of functions would be in memory, which would simply slow everything down.

    Plus, then you need a way to initialize the lookup function for each and every function.
    not necessarily, if you create a .lib that exports all symbols you want to replace
    and you resolve every function the first time it's called the compiler optimizes the unused ones out (providing you do not have some global table that lists them all)

    see attached file for poc,
    only changes that i made to get it without imports was add one header and change referenced libraries in linker options

    @wav: this is without iat too.
    Attached Files
    - "Double the gun, double the fun!"

  15. #15
    Join Date
    May 2009
    Posts
    405
    Thanks
    3
    Thanked 7 Times in 5 Posts
    Blog Entries
    1
    Rep Power
    37

    Re: Import masking library

    Quote Originally Posted by learn_more View Post
    not necessarily, if you create a .lib that exports all symbols you want to replace
    and you resolve every function the first time it's called the compiler optimizes the unused ones out (providing you do not have some global table that lists them all)

    see attached file for poc,
    only changes that i made to get it without imports was add one header and change referenced libraries in linker options

    @wav: this is without iat too.
    I didn't look at the project because I just realized what you were saying; you mean rewrite functions, such as MessageBoxA, to run my GPA/GMH functions, do the lookup, and hand off the parameters when they're called. Right?

    In that case, your method would be nice, but still, volatile. What if a function is added or a parameter type is altered? Then I'd have to update the static library file, which, over time, would become a pain to maintain.

    Not to mention, how do you expect me to get every function there is in the core library files (i.e. user32.dll and kernel32.dll) automatically?

    Also, this makes parsing a bit easier for an attacker; once they find the generic pattern in the .lib file, they can just cross-reference it with the executable. The great idea with this is, you can customize it, at least changing the hash_seed, so that nothing is exactly "static" in how it all works.

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

     

Similar Threads

  1. ping masking
    By MoleMan in forum Tutorial Requests
    Replies: 9
    Last Post: 05-10-2009, 06:51 AM
  2. msdn library
    By 12114 in forum Beginner
    Replies: 4
    Last Post: 01-08-2009, 07:17 AM
  3. Cannot find Import Name Table
    By drewpaul86 in forum Intermediate
    Replies: 1
    Last Post: 12-15-2004, 05:19 AM

Tags for this Thread

Posting Permissions

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