Example #1
0
        /// <summary>
        /// Decodes all the call instructions from the block. Return instructions are outputted to returnAddresses.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="baseAddress"></param>
        /// <param name="returnAddresses"></param>
        /// <returns></returns>
        public static List <SIMPLE_INSTRUCTION> DisassembleBlockCallsOnly(byte[] data, int baseAddress, ref oAsmRetList returnAddresses, ref oEbpArgumentList ebpArguments, ref List <jmpInstruction> jumps)
        {
            // Disassemble all the instructions in the data block
            int offset = 0;
            List <SIMPLE_INSTRUCTION> result = new List <SIMPLE_INSTRUCTION>(data.Length / 100);

            while (offset + 10 < data.Length)
            {
                // Process this instruction

                // Decode
                SIMPLE_INSTRUCTION instruction = decodeInstruction(data, offset, baseAddress);

                // Process
                switch (instruction.opcode)
                {
                case SIMPLE_INSTRUCTION.OP_CALL_IMM32:
                    if (instruction.size == 5 && instruction.numPrefix == 0)
                    {
                        result.Add(instruction);
                    }
                    break;

                case SIMPLE_INSTRUCTION.OP_RET_NULL:
                    if (instruction.size == 1 && instruction.numPrefix == 0)
                    {
                        returnAddresses.addRet(instruction.address, 0);
                    }
                    break;

                case SIMPLE_INSTRUCTION.OP_RET_IMM16:
                    if (instruction.size == 3 && instruction.numPrefix == 0)
                    {
                        returnAddresses.addRet(instruction.address, instruction.immediate);
                    }
                    break;

                case SIMPLE_INSTRUCTION.OP_MOV_REG32:
                    if (instruction.size == 3 && (data[offset + 1] == 0x45 || data[offset + 1] == 0x5d ||
                                                  data[offset + 1] == 0x4D || data[offset + 1] == 0x55 ||
                                                  data[offset + 1] == 0x75 || data[offset + 1] == 0x7D) &&
                        data[offset + 2] <= 0x7F && data[offset + 2] > 0x04)
                    {
                        // mov reg32, [ebp+imm8]
                        // Save this immediate value, it tells us how many arguments this function has
                        ebpArguments.addEbpReference(instruction.address, (int)(data[offset + 2] - 4) / 4);
                    }
                    break;

                case SIMPLE_INSTRUCTION.OP_PUSH_DEREF_REG32:
                    if (instruction.size == 3 && data[offset + 1] == 0x75 &&
                        data[offset + 2] <= 0x7F && data[offset + 2] > 0x04)
                    {
                        // push [ebp+imm8]
                        // Save this immediate value, it tells us how many arguments this function has
                        ebpArguments.addEbpReference(instruction.address, (int)(data[offset + 2] - 4) / 4);
                    }
                    break;

                case SIMPLE_INSTRUCTION.OP_JMP_IMM32:
                    if (instruction.size == 5)
                    {
                        // jmp imm32
                        // Save this jump
                        jumps.Add(new jmpInstruction(instruction.address, instruction.jmp_target));
                    }
                    break;
                }

                // Check to see if it is a mov reg32, [ebp+imm8] instruction.

                // Next instruction
                offset += instruction.size;
            }

            // Return the resulting call instructions
            return(result);
        }
        /// <summary>
        /// Estimates the number of input parameters of each funciton.
        /// </summary>
        /// <param name="retList">Return instruction list.</param>
        public static void estimateFunctionParameters(oAsmRetList retList, oEbpArgumentList ebpAddresses, Form parent)
        {
            if( functions == null ) functions = new List<oFunction>();

            // Estimate the number of parameters for each function return
            int count = 0;
            formProgress progress = new formProgress(parent);
            progress.Show(parent);
            progress.setMin(0);
            progress.setMax(oFunctionMaster.numFunctions/273);
            progress.setTitle("Estimating Number Parameter Counts...");
            progress.setLabel1("Estimating Function Input Parameter Counts: " + count.ToString() + "0 of " + oFunctionMaster.numFunctions.ToString() );
            progress.setLabel2("");

            // Loop through each function, estimating the number of parameters
            List<oFunction> invalidFunctions = new List<oFunction>(0);
            foreach( oFunction function in functions )
            {
                // Estimate parameters
                function.estimateNumParameters(retList, ebpAddresses);

                // Check the number of parameters is valid
                if (function.getNumParams() > 50)
                {
                    // Invalid function
                    invalidFunctions.Add( function );
                }

                count++;
                if(count%273 == 0)
                {
                    progress.setLabel1("Estimating Function Input Parameter Counts: " + count.ToString() + "0 of " + oFunctionMaster.numFunctions.ToString());
                    progress.increment();
                }
            }

            // Remove the invalid functions
            foreach( oFunction function in invalidFunctions )
            {
                functions.Remove(function);
            }

            progress.Dispose();
        }
        /// <summary>
        /// Decodes all the call instructions from the block. Return instructions are outputted to returnAddresses.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="baseAddress"></param>
        /// <param name="returnAddresses"></param>
        /// <returns></returns>
        public static List<SIMPLE_INSTRUCTION> DisassembleBlockCallsOnly(byte[] data, int baseAddress, ref oAsmRetList returnAddresses, ref oEbpArgumentList ebpArguments, ref List<jmpInstruction> jumps)
        {
            // Disassemble all the instructions in the data block
            int offset = 0;
            List<SIMPLE_INSTRUCTION> result = new List<SIMPLE_INSTRUCTION>(data.Length/100);
            while( offset + 10 < data.Length)
            {
                // Process this instruction

                // Decode
                SIMPLE_INSTRUCTION instruction = decodeInstruction(data, offset, baseAddress);

                // Process
                switch(instruction.opcode)
                {
                    case SIMPLE_INSTRUCTION.OP_CALL_IMM32:
                        if( instruction.size == 5 && instruction.numPrefix == 0 )
                            result.Add(instruction);
                        break;
                    case SIMPLE_INSTRUCTION.OP_RET_NULL:
                        if (instruction.size == 1 && instruction.numPrefix == 0)
                            returnAddresses.addRet(instruction.address, 0);
                        break;
                    case SIMPLE_INSTRUCTION.OP_RET_IMM16:
                        if (instruction.size == 3 && instruction.numPrefix == 0)
                            returnAddresses.addRet(instruction.address, instruction.immediate);
                        break;
                    case SIMPLE_INSTRUCTION.OP_MOV_REG32:
                        if (instruction.size == 3 && (data[offset+1] == 0x45 || data[offset+1] == 0x5d ||
                                                      data[offset+1] == 0x4D || data[offset+1] == 0x55 ||
                                                      data[offset+1] == 0x75 || data[offset+1] == 0x7D) &&
                            data[offset + 2] <= 0x7F && data[offset + 2] > 0x04)
                        {
                            // mov reg32, [ebp+imm8]
                            // Save this immediate value, it tells us how many arguments this function has
                            ebpArguments.addEbpReference(instruction.address, (int) (data[offset + 2]-4)/4);
                        }
                        break;
                    case SIMPLE_INSTRUCTION.OP_PUSH_DEREF_REG32:
                        if (instruction.size == 3 && data[offset + 1] == 0x75 &&
                            data[offset + 2] <= 0x7F && data[offset + 2] > 0x04)
                        {
                            // push [ebp+imm8]
                            // Save this immediate value, it tells us how many arguments this function has
                            ebpArguments.addEbpReference(instruction.address, (int)(data[offset + 2] - 4) / 4);
                        }
                        break;
                    case SIMPLE_INSTRUCTION.OP_JMP_IMM32:
                        if (instruction.size == 5)
                        {
                            // jmp imm32
                            // Save this jump
                            jumps.Add( new jmpInstruction(instruction.address, instruction.jmp_target) );
                        }
                        break;

                }

                // Check to see if it is a mov reg32, [ebp+imm8] instruction.

                // Next instruction
                offset += instruction.size;
            }

            // Return the resulting call instructions
            return result;
        }