Exemplo n.º 1
0
 public oAsmRetList()
 {
     rets     = new List <retAddress>(50000);
     comparer = new retAddress.COMPARER_ADDRESS();
 }
Exemplo n.º 2
0
        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);
        }