public oAsmRetList() { rets = new List <retAddress>(50000); comparer = new retAddress.COMPARER_ADDRESS(); }
private static byte[] getLinearCodeToRet(Process process, HEAP_INFO heap, uint address, List <jmpInstruction> jmps_in, List <retAddress> rets, uint maxLength) { // This gets the block of data starting at address, following all force jumps, and ending at the first return. byte[] result = new byte[0]; bool cloned = false; List <jmpInstruction> jmps = jmps_in; uint curAddress = address; retAddress.COMPARER_ADDRESS retComparer = new retAddress.COMPARER_ADDRESS(); jmpInstructionComparer jmpComparer = new jmpInstructionComparer(); while (curAddress >= heap.heapAddress && curAddress < heap.heapAddress + heap.heapLength) { // Find the next return or jump - whichever comes first. // Find the next return int retIndex = rets.BinarySearch(new retAddress(curAddress, 0), retComparer); if (retIndex < 0) { retIndex = ~retIndex; } uint nextRet = uint.MaxValue; if (retIndex < rets.Count && retIndex >= 0) { nextRet = rets[retIndex].address; } // Find the next jump int jmpIndex = jmps.BinarySearch(new jmpInstruction(curAddress, 0), jmpComparer); if (jmpIndex < 0) { jmpIndex = ~jmpIndex; } uint nextJmp = uint.MaxValue; if (jmpIndex < jmps.Count && jmpIndex >= 0) { nextJmp = jmps[jmpIndex].address; } // Make sure we found either a next jump or return if (nextJmp != uint.MaxValue || nextRet != uint.MaxValue) { // Add this region to the result uint blockEnd = (nextJmp > nextRet ? nextRet : nextJmp) - 1; uint newLength = (uint)result.Length + (blockEnd - curAddress + 1); if (newLength > maxLength) { newLength = maxLength; } byte[] newResult = new byte[newLength]; Array.ConstrainedCopy(result, 0, newResult, 0, result.Length); byte[] tmp = oMemoryFunctions.ReadMemory(process, curAddress, (uint)(newResult.Length - result.Length)); Array.ConstrainedCopy(tmp, 0, newResult, result.Length, tmp.Length); result = newResult; // Check if we have gathered enough bytes if (result.Length >= maxLength) { return(result); } // If this is a return we are done, jmp we need to update the current address if (nextJmp > nextRet) { // We hit the return statement next. We are done. return(result); } else { // Update the current address to the jmp target curAddress = jmps[jmpIndex].destination; // Delete this jmp so that we do not follow it more than once if (!cloned) { jmps = new List <jmpInstruction>(jmps_in); cloned = true; } jmps.RemoveAt(jmpIndex); } } else { // No return or jump coming up, we are done. return(result); } } // We jumped out of this heap. Stop analysis. return(result); }