Prevent detouring functions. Avoid cracking - c#

There is an application that checks for activation using DLL Check function. Check returns 1 if application is activated and 0 otherwise. I create simple application and DLL containing function MyCheck (which always returns 1) with the same signature and detoured Check function with my version using MS detours lib for function hooking. Obviously it works and the application is successfully cracked, so I need to avoid it.
I tried to call Check function directly (by specifying exact address), without even using GetProcAddress, but looks like detours lib is modifying the function body itself, not export table.
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate bool CheckFunctionDelegate();
static void Main(string[] args)
{
ProcessModule module = Process.GetCurrentProcess().Modules
.Cast<ProcessModule>()
.First(m => m.ModuleName == "licensing_check.dll");
IntPtr procedurePtr = IntPtr.Add(module.BaseAddress, 0x00003FF0);
// Calling validation function by pointer
CheckFunctionDelegate checkFunction = (CheckFunctionDelegate)
Marshal.GetDelegateForFunctionPointer(procedurePtr, typeof(CheckFunctionDelegate));
if (checkFunction())
{
// do some stuff
}
}
}
Then I tried to read function body and I see that after detour MD5 checksum differs from the original one. So I'm trying to read entire contents of DLL in memory and check it to confirm that DLL contents are not changed, but it doesn't work either. It throws AccessViolationException.
Process.EnterDebugMode();
ProcessModule module = Process.GetCurrentProcess().MainModule;
byte[] data = new byte[module.ModuleMemorySize];
Marshal.Copy(module.BaseAddress, data, 0, module.ModuleMemorySize);
I used MainModule here, but it gives the same error for each module in Process.GetCurrentProcess().Modules collection.
I would appreciate any help on this, I'm not necessarily expecting to solve it in one of the ways I describe, any good solution is acceptable.
Thanks.

Related

G1ANT - disposing of unmanaged code in C# macros

I am enjoying using G1ANT's "macros" capability to call unmanaged code, but the unmanaged objects are of course not being automatically garbage collected absent code to do it.
My request is specifically for best practices in disposing of unmanaged code in these G1ANT C# macros, not for disposing of the same in C# generally, and it is not a request to fix the code below, which runs as is just fine.
If I were coding in C# using Visual Studio, I would likely use a System.Runtime.InteropServices.SafeHandle class, override the Finalize method, or use one of the other approaches in common use (see also this post on disposing of unmanaged objects in C#).
But none of these approaches appear to be a good fit for G1ANT macros per se, at least with my novice experience of them.
For illustration purposes I'm referring to this G1ANT code, but WITHOUT the last line in the macro (ahk.Reset()), because it runs fine with that line, more than once. (I'm painfully aware that there must be a much better example, but as I'm new to G1ANT, this is the only thing I have so far.) What I'm after is C# code that works in G1ANT when there is no explicit disposal of the unmanaged object:
addon core version 4.100.19170.929
addon language version 4.100.19170.929
-dialog ♥macrodlls
♥macrodlls = System.dll,System.Drawing.dll,System.Windows.Forms.dll,AutoHotkey.Interop.dll,System.Runtime.InteropServices.dll
-dialog ♥macrodlls
♥macronamespaces = System,AutoHotkey.Interop,System.Windows.Forms
⊂
var ahk = AutoHotkeyEngine.Instance;
//Load a library or exec scripts in a file
ahk.LoadFile("functions.ahk");
//execute a specific function (found in functions.ahk), with 2 parameters
ahk.ExecFunction("MyFunction", "Hello", "World");
string sayHelloFunction = "SayHello(name) \r\n { \r\n MsgBox, Hello %name% \r\n return \r\n }";
ahk.ExecRaw(sayHelloFunction);
//execute's newly made function\
ahk.ExecRaw(#"SayHello(""Mario"") ");
var add5Results = ahk.ExecFunction("Add5", "5");
MessageBox.Show("ExecFunction: Result of 5 with Add5 func is" + add5Results);
addon core version 4.100.19170.929
addon language version 4.100.19170.929
-dialog ♥macrodlls
♥macrodlls = System.dll,System.Drawing.dll,System.Windows.Forms.dll,AutoHotkey.Interop.dll,System.Runtime.InteropServices.dll,System.Reflection.dll,Microsoft.CSharp.dll
-dialog ♥macrodlls
♥macronamespaces = System,AutoHotkey.Interop,System.Windows.Forms,System.Reflection
⊂
var ahk = AutoHotkeyEngine.Instance;
//Load a library or exec scripts in a file
ahk.LoadFile("functions.ahk");
//execute a specific function (found in functions.ahk), with 2 parameters
ahk.ExecFunction("MyFunction", "Hello", "World");
string sayHelloFunction = "SayHello(name) \r\n { \r\n MsgBox, Hello %name% \r\n return \r\n }";
ahk.ExecRaw(sayHelloFunction);
//executes new function
ahk.ExecRaw(#"SayHello(""Mario"") ");
var add5Results = ahk.ExecFunction("Add5", "5");
MessageBox.Show("ExecFunction: Result of 5 with Add5 func is" + add5Results);
ahk.Reset();
⊃
⊃
It's taken nearly verbatim from the AutoHotkey.Interop github page.
Without the last line in the macro ('ahk.Reset()), the code runs perfectly the first time through, but on the second run G1ANT still sees the included AutoHotkey file, and warns of duplicate function definitions, but continues and still functions properly. The as-far-as-I-can-tell-undocumented AutoHotkey.Interop command Reset() takes care of the garbage collection problem by calling
public void Terminate()
{
AutoHotkeyDll.ahkTerminate(1000);
}
public void Reset() {
Terminate();
AutoHotkeyDll.ahkReload();
AutoHotkeyDll.ahktextdll("", "", "");
}
Thus, the AutoHotkeyEngine instance itself appears to be garbage collected, even without the ahk.Reset();, but the AutoHotkey script it loads into an object is not.
Stopping the G1ANT.Robot application and restarting, then reloading the script above (as mentioned, without the line ahk.Reset();), works just fine, but once again only for a single run.
Edit: The given answer's advice on treatment of singletons is what I will use henceforth when loading of AutoHotkey function scripts and the DLL itself. It seems prudent and good practice to check to see if the DLL or function file have been loaded, whether problems exist or not. "An ounce of prevention", etc. In addition, I have forked the AutoHotkey.Interop repo here, adding a boolean check to see if the AutoHotkeyEngine instance is ready.
Best regards,
burque505
You use AutoHotkeyEngine.Instance, so I guess it's a singleton. It will stay loaded in memory as long as the corresponding dll is kept there, and the latter is loaded and lives as long as the its domain lives. The macro app domain (the place where script stuff is placed) currently lives as long as Robot's app domain, so in fact your singleton instance lives as long as Robot.
Either:
don't use singleton,
or reset it right after obtaining the instance (kinda what you already did),
or treat it as a singleton that has life span longer than your app. In this case after obtaining singleton instance do a check if your functions file has been already loaded and only load it if it wasn't done already.

Is it possible to patch a dotnet function on the fly

Recently I found an architect-often-used .net program has implemented a function wrongly. So I successfully patched it using ILSpy and Reflexil in a static way of modifying binaries. However, it is annoying that you need to patch it and remove StrongNameCheck again when new minor version releases. (btw, the author believes it is a feature instead of a bug)
Hopefully, the program fully supports assemblies as a plugin. And my target is a public non-static member function in a public class which can be directly called by plugins. Is there a way to patch the function on the fly?
I usually use some APIHook tricks in unmanaged C++ but dotnet is really a different thing. In this case, I want the modification still valid after my assembly unloads (so more similar to a patch, not a hook).
Yes you can do it with code injection. But you need to know some MSIL. There is also a library for that which is called Mono.Cecil.
Here is a example code
Console.WriteLine("> INJECTING INTO 12345.EXE..." + Environment.NewLine);
AssemblyDefinition asm = AssemblyDefinition.ReadAssembly(#"C:\dummy.exe");
var writeLineMethod = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });
var writeLineRef = asm.MainModule.Import(writeLineMethod);
var pStartMethod = typeof(Process).GetMethod("Start", new Type[] { typeof(string) });
var pStartRef = asm.MainModule.Import(pStartMethod);
foreach (var typeDef in asm.MainModule.Types)
{
foreach (var method in typeDef.Methods)
{
//Let's push a string using the Ldstr Opcode to the stack
method.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Ldstr, "INJECTED!"));
//We add the call to the Console.WriteLine() method. It will read from the stack
method.Body.Instructions.Insert(1, Instruction.Create(OpCodes.Call, writeLineRef));
//We push the path of the executable you want to run to the stack
method.Body.Instructions.Insert(2, Instruction.Create(OpCodes.Ldstr, #"calc.exe"));
//Adding the call to the Process.Start() method, It will read from the stack
method.Body.Instructions.Insert(3, Instruction.Create(OpCodes.Call, pStartRef));
//Removing the value from stack with pop
method.Body.Instructions.Insert(4, Instruction.Create(OpCodes.Pop));
}
}
asm.Write("12345.exe"); //Now we just save the new assembly
Don't monkey patch code. Add the functionality to your code base and call that function. Or write an adapter class that wraps the underlying assembly, which is much neater.
If the author of the code thinks it's not a bug then it may be in there for reasons you don't understand and could be part of any number of bug fixes.

Attempted to read or write protected memory when using reflection to call dll functions

I have made a plugin system that uses reflection to call functions in a plugin. A plugin has to implement the IPlugin interface to be used.
In the application which uses the plugins the plugin instance is created with the following code:
Assembly currentAssembly = Assembly.LoadFrom(startInfo.PluginAssemblyPath);
Type[] types = currentAssembly.GetTypes();
IPlugin pluginInstance = null;
foreach (Type type in types)
{
if (type.FullName == startInfo.PluginTypeName)
{
pluginInstance = (IPlugin)Activator.CreateInstance(type);
}
}
if (pluginInstance == null)
{
throw new Exception("Plugin loader error: Could not instantiate plugin: " + startInfo.ToString()); }
return pluginInstance;
I have made a plugin that uses some unmannaged dll's. When I call the IPlugin interface functions in a test project in the plugin solution everything works fine. But when I call the plugin via the plugin instance made in the code shown above I get the System.AccessViolationException: Attempted to read or write protected memory error when calling functions in the unmannaged dll's.
The unmannaged dll's are c++ dll's made by a third party. I tried enabling native code debugging but i do not have the .pdb files.
I am not sure why this is happening, is this because of the reflection? Or can there be other causes?
Edit:
In the stack I can see the unmannaged function being called:
[MarshalAs(UnmanagedType.LPStr)]
private readonly StringBuilder sb = new StringBuilder(256);
[DllImport("x.dll", EntryPoint = "xLib")]
static extern int _xLib(int a1, int a2, int a3, int a4, int a5, int a6, [Out]StringBuilder str);
The exception is thrown when calling the _xLib function.
Edit: Somewhere in this _xLib function the following function is called:
handle = x_Open();
which is in an other dll and is defined as:
DllExport x_Handle *x_Open();
As soon as anything in the handle is used like:
"%s", handle->x.string
The exception is thrown.
I still do not understand why this is working in the test project and not when I am using it in the app as a plugin.
Maybe you have to pin the StringBuilder to allow unmanaged code to interact with it.
Pinned object is one that is not allowed to move. The garbage collector is normally compacting the memory in that it moves all objects to "one or more clusters". This is to create large chunks of free space.
This basically means if someone else (outside) has a pointer to the memory address of an object, this may point to random content - as the object has moved.
Pinning an object tells the GC to NOT MOVE IT. This is normally useless and ONLY makes sense when working with pointers - like when using PInvoke... and I can see a pointer to a StringBuilder instance in _xlib function
Well after some intensive debugging I found the problem was the handle having some wrong address which caused the violation. The cause of the address being wrong was the x_open function loaded yet another dll with the LoadLibraryA function. This dll was not in the same directory as the executable file so it was not found.
I solved it by adding the directory of this last dll to the environment path.

Determining interop function caller

I'm exposing a C# class to COM using these attributes:
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
[GuidAttribute("2325EBEB-DB5F-4D29-B220-64845379D9C5")]
[ComSourceInterfaces(typeof(WrapperEvents))]
in this class I have a function:
public void shutdownService()
This function is meant to be called just once from a VB6 client via COM Interop. Everything works fine. But somehow, it's being called more than once. My C# codes doesn't call this function directly. So I'm guessing the problem is in VB6 code. Unfortunately, that's not what the VB6 team thinks.
Is there a way to determine the caller of this function, ie. from my C#code or the VB6 code?
Right now I'm using a simple function to get the stacktrace:
public void LogStack()
{
var trace = new System.Diagnostics.StackTrace();
foreach (var frame in trace.GetFrames())
{
var method = frame.GetMethod();
if (method.Name.Equals("LogStack")) continue;
logger.Debug(string.Format("LogStack: {0}::{1}",
method.ReflectedType != null ? method.ReflectedType.Name : string.Empty, method.Name));
}
}
Obviously, I got somthing like this on the log:
2011-12-23 08:28:40,067 1 DEBUG (null) LogStack: Service::shutdownService
Since the only line of LogStack is the COM exposed function, I assume it's being called from vb6. But that's not enough proof for the VB6 team. Any idea how to really prove where function ?
You can try several things:
set a breakpoint in your code to trigger the debugger, then look at the call stack.
You could do an application dump here from visual studio and send it to them or screenshot the stack.
ex. Debugger.Break
http://www.netsplore.com/PublicPortal/blog.aspx?EntryID=12
Dump with "Savre Dump As"
http://msdn.microsoft.com/en-us/library/d5zhxt22.aspx
Use the com tracing
from a system level see
http://support.microsoft.com/kb/926098
I also recall a tool being installed with visual studio 6 do to this as well

Call function from DLL with non-static path

I have a DLL that I need to access methods from.
In most cases like this I just use [DllImport] to access methods from unmanaged assemblies, but the problem with that in this situation is that it requires the path to the DLL at instantiation time, so a constant string.
This particular DLL is one that gets installed with my application and I can't guarantee where it will be after the program is installed (I'd rather not put it somewhere static like %SystemRoot%).
So is there a way in C# that I can declare and use a method from a DLL at runtime with a variable path?
Any ideas or suggestions would be greatly appreciated!
This is a bit of hack, but since you say that you can find the path to the dll at runtime, why not copy it to your current working directory before you use any of the functions? That way, the dll will exist next to your exe and will be found by LoadLibrary. No need for any additional path in your DllImport.
The only other way to use a method from a dynamic path is to do this:
1) Do the necessary P/Invoke signatures for LoadLibrary & GetProcAddress
2) Load the library from the desired path (LoadLibrary)
3) Find the desired function (GetProcAddress)
4) Cast the pointer to a delegate Marshal.GetDelegateForFunctionPointer
5) Invoke it.
Of course, you will need to declare a delegate for each function you want to "import" in this way since you have to cast the pointer to a delegate.
Don't use a path at all. Windows uses a default method of searching for DLLs when trying to dynamically or statically load a function from it.
The exact search logic is documented at MSDN in the docs for LoadLibrary - basically, if the DLL is just used by your app, put in the same folder as your application during the install and don't worry about it. If it's a commonly used DLL, put it somewhere in the folder structure searched by LoadLibrary() and it'll get found.
I had a similar situation. I use DLLs from a SDK that is installed on the machine. I get the directory location of the DLLs from that SDKs registry key. I set the DLL location on the executing users PATH variable (only temporary modification). Basically it allows you to set a dynamic path for the DLL you want to invoke, so it don't have to be from registry. Mind that the PATH var is the last place Windows looks for DLLs. But on the other hand, it does not change the other places Windows looks for DLLs.
Example:
API i want to call, on the DLL:
[DllImport("My.DLL")]
private static extern IntPtr ApiCall(int param);
Get the registry key (you need using Microsoft.Win32;):
private static string GetRegistryKeyPath() {
string environmentPath = null;
using (var rk = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\SOMENNAME"))
{
if (rk != null)
{
environmentPath = rk.GetValue("Path(or whatever your key is)").ToString();
}
if (string.IsNullOrEmpty(environmentPath))
{
Log.Warn(
string.Format("Path not found in Windows registry, using key: {0}. Will default to {1}",
#"SOFTWARE\SOMETHING", #"C:\DefaultPath"));
environmentPath = #"C:\DefaultPath";
}
}
return environmentPath;
}
Add the path of the DLL on the PATH var (Concat() is found in Linq):
void UpdatePath(IEnumerable<string> paths){
var path = new[] { Environment.GetEnvironmentVariable("PATH") ?? "" };
path = path.Concat(paths);
string modified = string.Join(Path.PathSeparator.ToString(), path);
Environment.SetEnvironmentVariable("PATH", modified);
}
Start Using the API call:
var sdkPathToAdd = GetRegistryKeyPath();
IList<string> paths = new List<string>
{
Path.Combine(sdkPathToAdd),
Path.Combine("c:\anotherPath")
};
UpdatePath(paths);
//Start using
ApiCall(int numberOfEyes);

Categories