Example #1
0
        /// <summary>
        /// Add first RET in the data block to the return address list.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="baseAddress"></param>
        /// <param name="returnAddresses"></param>
        /// <returns></returns>
        public static void AddFirstRet(byte[] data, int baseAddress, int startOffset, ref oAsmRetList returnAddresses)
        {
            // Disassemble all the instructions in the data block
            int offset = startOffset;

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

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

                // Process
                switch (instruction.opcode)
                {
                case SIMPLE_INSTRUCTION.OP_RET_NULL:
                    if (instruction.size == 1)
                    {
                        returnAddresses.addRet(instruction.address, 0);
                    }
                    return;

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

                // Next instruction
                offset += instruction.size;
            }
        }
        /// <summary>
        /// Add first RET in the data block to the return address list.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="baseAddress"></param>
        /// <param name="returnAddresses"></param>
        /// <returns></returns>
        public static void AddFirstRet(byte[] data, int baseAddress, int startOffset, ref oAsmRetList returnAddresses)
        {
            // Disassemble all the instructions in the data block
            int offset = startOffset;
            while (offset + 10 < data.Length)
            {
                // Process this instruction

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

                // Process
                switch (instruction.opcode)
                {
                    case SIMPLE_INSTRUCTION.OP_RET_NULL:
                        if (instruction.size == 1)
                            returnAddresses.addRet(instruction.address, 0);
                        return;
                    case SIMPLE_INSTRUCTION.OP_RET_IMM16:
                        if (instruction.size == 3)
                            returnAddresses.addRet(instruction.address, instruction.immediate);
                        return;
                }

                // Next instruction
                offset += instruction.size;
            }
        }
Example #3
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>
        /// 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;
        }