• Import masking library

    Introducing my own little API redirection-type library!

    The goal of this library is to securely mask imports, so they cannot be found on-disk, and so that finding what is called during runtime becomes more difficult.

    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
    This article was originally published in forum thread: Import masking library started by Guy View original post
    Comments 30 Comments
    1. wav's Avatar
      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
    1. Guy's Avatar
      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.
    1. atom0s's Avatar
      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.
    1. Guy's Avatar
      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.
    1. wav's Avatar
      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
    1. Guy's Avatar
      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).
    1. Guy's Avatar
      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
    1. Guy's Avatar
      (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
    1. learn_more's Avatar
      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?
    1. Guy's Avatar
      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.
    1. wav's Avatar
      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
    1. temp2's Avatar
      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 ...
    1. learn_more's Avatar
      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.
    1. Guy's Avatar
      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.
    1. learn_more's Avatar
      Quote Originally Posted by Guy View Post
      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?
      i made a parser thatll parse the user32.lib; kernel32.lib and some others that are provided with the compiler

      you only need to know the number of arguments and calling convention, the datatype doesnt matter

      as for the generic attack: the resolving can be virtualized/randomized/whatever
    1. wav's Avatar
      static library is bad and leaves a giant hole for them to abuse you with ( size, any referenced strings, exports, etc )
    1. learn_more's Avatar
      Quote Originally Posted by wav View Post
      static library is bad and leaves a giant hole for them to abuse you with ( size, any referenced strings, exports, etc )
      0 referenced strings, size depends on amount of imports hidden with it, no exports
    1. wav's Avatar
      The biggest problem is the size. I'm fairly certain that the linker should be smart enough to only link the functions that are actually used.
    1. Guy's Avatar
      "0 referenced strings, size depends on amount of imports hidden with it, no exports"

      I hope you're using the compile-time string hashing functions in my library

      Anyways, virtualizing the lookup procedure won't protect anything; once someone finds where you store all the lookups, and how they're all in the same place, it's all over for you. That is, unless you encrypt them, in which case, you will want to obfuscate the lookup procedure. But, if you obfuscate it, then it can get very, very slow; then again, that's up to you.

      Regardless, like I said, feel free to contribute
    1. learn_more's Avatar
      attached are all functions from kernel32 / user32 parsed from windows 2003 platform sdk,
      an own loadlibrary and getprocaddress implementation needs to be added, aswell as an optional string encryption.

      these are the compiler settings i use for adding my own lib and having the linker shutup about some warnings:
      Code:
      	"Linker"->"Command Line" add:  "/ignore:4049"
      "Linker"->"Input"->"Additional dependencies" add: 
      your lib generated with the file attached here.lib
      winspool.lib
      comdlg32.lib
      advapi32.lib
      gdi32.lib
      comdlg32.lib
      opengl32.lib
      shell32.lib
      comctl32.lib
      shell32.lib
      ole32.lib
      oleaut32.lib
      uuid.lib
      odbc32.lib
      odbccp32.lib
      
      and untick: inhereit