/// <summary> /// This function injects the instrumentation code and /// redirects the call instructions and pe tables. /// </summary> public static bool inject(uint bufferSize, uint maxCallCount, List<HEAP_INFO> invalidCallSourceHeaps, Form parent) { if( functions.Count > 0 ) { // Create the progress bar formProgress progress = new formProgress(parent); progress.Show(); progress.setMin(0); progress.setMax(functions.Count / 457); progress.setTitle("Injecting Function Instrumentation Code..."); progress.setLabel1("Allocating buffer space..."); progress.setLabel2(""); // Create and setup the circular buffer recording buffer for the visualizations. uint visualizationAddress = (uint) oMemoryFunctions.VirtualAllocEx(oProcess.activeProcess.Handle, (IntPtr) 0, 20000000 + 1000, (uint) (MEMORY_STATE.COMMIT), (uint) MEMORY_PROTECT.PAGE_READWRITE ); injectedHeapAddress1 = visualizationAddress; injectedHeapSize1 = 20000000 + 1000; oMemoryFunctions.WriteMemoryDword(oProcess.activeProcess, visualizationAddress+4, 0); oAssemblyGenerator.addCommonAddress(visualizationAddress+4, "VIS_AD_CIRCULAR_OFFSET"); oAssemblyGenerator.addCommonAddress(bufferSize * 1000000 - 8 - 4, "VIS_CIRCULAR_SIZE"); oAssemblyGenerator.addCommonAddress(visualizationAddress+16+4, "VIS_AD_CIRCULAR_BASE"); oAssemblyGenerator.addCommonAddress(0, "mainRecordFunction"); //MessageBox.Show((visualizationAddress + 16).ToString("X")); // Create the visualization buffer reader reader_visualization = new oCircularBufferReader(visualizationAddress + 16 + 4, bufferSize * 1000000 - 4, visualizationAddress + 4); // Set the global buffer parameters oMemoryFunctions.WriteMemoryDword(oProcess.activeProcess, visualizationAddress, maxCallCount); oAssemblyGenerator.addCommonAddress(visualizationAddress, "MAXCALLS"); // Determine the size per function int sizePerFunc = ((oFunction)functions[0]).generateInstrumentation(10000).Length; // Allocate the memory heap for the funciton code injections uint currentAddress = (uint)oMemoryFunctions.VirtualAllocEx(oProcess.activeProcess.Handle, (IntPtr) 0, functions.Count * sizePerFunc + 1000 + 2*0x80000, // 1000 + 2*0x80000 bytes for the mainRecordFunction (uint)(MEMORY_STATE.COMMIT), (uint)MEMORY_PROTECT.PAGE_EXECUTE_READWRITE ); injectedHeapAddress2 = currentAddress; injectedHeapSize2 = (uint) (functions.Count * sizePerFunc + 1000 + 2*0x80000); if (currentAddress == 0) { oConsole.printMessageShow("ERROR: Could not allocate memory space in target process for code injections."); progress.Dispose(); return false; } progress.setLabel1("Injecting common base functions." ); // Inject the common function oAssemblyGenerator.addCommonAddress(currentAddress, "mainRecordFunction"); uint size = (uint) oFunction.injectCommonCode(currentAddress); // Generate and write the valid read pointer table progress.setLabel1("Generating and injecting the read pointer dereference lookup table."); // Get the address of the table table_addressValidReadTable = UInt32.Parse(oMemoryFunctions.ReverseString(oAssemblyGenerator.evaluateCommonAddress("sLOOKUPVALIDPOINTER", 0, currentAddress)), NumberStyles.HexNumber); updateValidReadPointerTable(); // Generate and write the excluded call source table progress.setLabel1("Generating and injecting the exclusion source lookup table."); // Get the address of the table table_addressInvalidSourceTable = UInt32.Parse(oMemoryFunctions.ReverseString(oAssemblyGenerator.evaluateCommonAddress("sLOOKUPINVALIDSOURCE", 0, currentAddress)), NumberStyles.HexNumber); updateInvalidCallSourceTable(invalidCallSourceHeaps); // Set the size to dereference option dereferenceSizeAddress = UInt32.Parse(oMemoryFunctions.ReverseString(oAssemblyGenerator.evaluateCommonAddress("sSTRINGDEREFERENCESIZE", 0, currentAddress)), NumberStyles.HexNumber); oMemoryFunctions.WriteMemoryDword(oProcess.activeProcess, dereferenceSizeAddress, (uint) Properties.Settings.Default.NumDereferencedBytes); currentAddress += size; // Perform the intecept function code injection int count = 0; progress.setLabel1("Injecting instrumentation functions and redirecting functions: " + count.ToString() + " of " + functions.Count.ToString()); foreach (oFunction function in functions) { // Inject the instrumentation functions uint injectionAddress = currentAddress; size = (uint) function.injectInstrumentation(currentAddress); // Update the function parameters function.addressCount = UInt32.Parse(oMemoryFunctions.ReverseString(oAssemblyGenerator.evaluateCommonAddress("sCOUNT", 0, currentAddress)), NumberStyles.HexNumber); function.addressRecord = UInt32.Parse(oMemoryFunctions.ReverseString(oAssemblyGenerator.evaluateCommonAddress("sSAVEDATA", 0, currentAddress)), NumberStyles.HexNumber); // Redirect the function calls function.redirect(injectionAddress); currentAddress += size; // Update the progress bar count++; if ((count % 457) == 0) { progress.setLabel1("Injecting instrumentation functions and redirecting functions: " + count.ToString() + " of " + functions.Count.ToString()); progress.increment(); } } progress.Dispose(); } return true; }
/// <summary> /// This function injects the instrumentation code and /// redirects the call instructions and pe tables. /// </summary> public static bool inject(uint bufferSize, uint maxCallCount, List <HEAP_INFO> invalidCallSourceHeaps, Form parent) { if (functions.Count > 0) { // Create the progress bar formProgress progress = new formProgress(parent); progress.Show(); progress.setMin(0); progress.setMax(functions.Count / 457); progress.setTitle("Injecting Function Instrumentation Code..."); progress.setLabel1("Allocating buffer space..."); progress.setLabel2(""); // Create and setup the circular buffer recording buffer for the visualizations. uint visualizationAddress = (uint)oMemoryFunctions.VirtualAllocEx(oProcess.activeProcess.Handle, (IntPtr)0, 20000000 + 1000, (uint)(MEMORY_STATE.COMMIT), (uint)MEMORY_PROTECT.PAGE_READWRITE ); injectedHeapAddress1 = visualizationAddress; injectedHeapSize1 = 20000000 + 1000; oMemoryFunctions.WriteMemoryDword(oProcess.activeProcess, visualizationAddress + 4, 0); oAssemblyGenerator.addCommonAddress(visualizationAddress + 4, "VIS_AD_CIRCULAR_OFFSET"); oAssemblyGenerator.addCommonAddress(bufferSize * 1000000 - 8 - 4, "VIS_CIRCULAR_SIZE"); oAssemblyGenerator.addCommonAddress(visualizationAddress + 16 + 4, "VIS_AD_CIRCULAR_BASE"); oAssemblyGenerator.addCommonAddress(0, "mainRecordFunction"); //MessageBox.Show((visualizationAddress + 16).ToString("X")); // Create the visualization buffer reader reader_visualization = new oCircularBufferReader(visualizationAddress + 16 + 4, bufferSize * 1000000 - 4, visualizationAddress + 4); // Set the global buffer parameters oMemoryFunctions.WriteMemoryDword(oProcess.activeProcess, visualizationAddress, maxCallCount); oAssemblyGenerator.addCommonAddress(visualizationAddress, "MAXCALLS"); // Determine the size per function int sizePerFunc = ((oFunction)functions[0]).generateInstrumentation(10000).Length; // Allocate the memory heap for the funciton code injections uint currentAddress = (uint)oMemoryFunctions.VirtualAllocEx(oProcess.activeProcess.Handle, (IntPtr)0, functions.Count * sizePerFunc + 1000 + 2 * 0x80000, // 1000 + 2*0x80000 bytes for the mainRecordFunction (uint)(MEMORY_STATE.COMMIT), (uint)MEMORY_PROTECT.PAGE_EXECUTE_READWRITE ); injectedHeapAddress2 = currentAddress; injectedHeapSize2 = (uint)(functions.Count * sizePerFunc + 1000 + 2 * 0x80000); if (currentAddress == 0) { oConsole.printMessageShow("ERROR: Could not allocate memory space in target process for code injections."); progress.Dispose(); return(false); } progress.setLabel1("Injecting common base functions."); // Inject the common function oAssemblyGenerator.addCommonAddress(currentAddress, "mainRecordFunction"); uint size = (uint)oFunction.injectCommonCode(currentAddress); // Generate and write the valid read pointer table progress.setLabel1("Generating and injecting the read pointer dereference lookup table."); // Get the address of the table table_addressValidReadTable = UInt32.Parse(oMemoryFunctions.ReverseString(oAssemblyGenerator.evaluateCommonAddress("sLOOKUPVALIDPOINTER", 0, currentAddress)), NumberStyles.HexNumber); updateValidReadPointerTable(); // Generate and write the excluded call source table progress.setLabel1("Generating and injecting the exclusion source lookup table."); // Get the address of the table table_addressInvalidSourceTable = UInt32.Parse(oMemoryFunctions.ReverseString(oAssemblyGenerator.evaluateCommonAddress("sLOOKUPINVALIDSOURCE", 0, currentAddress)), NumberStyles.HexNumber); updateInvalidCallSourceTable(invalidCallSourceHeaps); // Set the size to dereference option dereferenceSizeAddress = UInt32.Parse(oMemoryFunctions.ReverseString(oAssemblyGenerator.evaluateCommonAddress("sSTRINGDEREFERENCESIZE", 0, currentAddress)), NumberStyles.HexNumber); oMemoryFunctions.WriteMemoryDword(oProcess.activeProcess, dereferenceSizeAddress, (uint)Properties.Settings.Default.NumDereferencedBytes); currentAddress += size; // Perform the intecept function code injection int count = 0; progress.setLabel1("Injecting instrumentation functions and redirecting functions: " + count.ToString() + " of " + functions.Count.ToString()); foreach (oFunction function in functions) { // Inject the instrumentation functions uint injectionAddress = currentAddress; size = (uint)function.injectInstrumentation(currentAddress); // Update the function parameters function.addressCount = UInt32.Parse(oMemoryFunctions.ReverseString(oAssemblyGenerator.evaluateCommonAddress("sCOUNT", 0, currentAddress)), NumberStyles.HexNumber); function.addressRecord = UInt32.Parse(oMemoryFunctions.ReverseString(oAssemblyGenerator.evaluateCommonAddress("sSAVEDATA", 0, currentAddress)), NumberStyles.HexNumber); // Redirect the function calls function.redirect(injectionAddress); currentAddress += size; // Update the progress bar count++; if ((count % 457) == 0) { progress.setLabel1("Injecting instrumentation functions and redirecting functions: " + count.ToString() + " of " + functions.Count.ToString()); progress.increment(); } } progress.Dispose(); } return(true); }