Added some useful IDA scripts (NPOTB).
Added some useful IDA scripts (NPOTB).
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/tools/ida_scripts/makesig.idc Sun Jul 29 02:51:50 2012 +0100
1.3 @@ -0,0 +1,126 @@
1.4 +#include <idc.idc>
1.5 +
1.6 +/* makesig.idc: IDA script to automatically create and wildcard a function signature.
1.7 + * Copyright 2012, Asher Baker
1.8 + *
1.9 + * This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
1.10 + *
1.11 + * Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
1.12 + *
1.13 + * 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
1.14 + *
1.15 + * 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
1.16 + *
1.17 + * 3. This notice may not be removed or altered from any source distribution.
1.18 +*/
1.19 +
1.20 +static main()
1.21 +{
1.22 + Wait(); // We won't work until autoanalysis is complete
1.23 +
1.24 + SetStatus(IDA_STATUS_WORK);
1.25 +
1.26 + auto pAddress = ScreenEA();
1.27 + pAddress = GetFunctionAttr(pAddress, FUNCATTR_START);
1.28 + if (pAddress == BADADDR)
1.29 + {
1.30 + Warning("Make sure you are in a function!");
1.31 + SetStatus(IDA_STATUS_READY);
1.32 + return;
1.33 + }
1.34 +
1.35 + auto sig;
1.36 + auto pFunctionEnd = GetFunctionAttr(pAddress, FUNCATTR_END);
1.37 +
1.38 + while (pAddress != BADADDR)
1.39 + {
1.40 + auto pInfo = DecodeInstruction(pAddress);
1.41 + if (!pInfo)
1.42 + {
1.43 + Warning("Something went terribly wrong D:");
1.44 + SetStatus(IDA_STATUS_READY);
1.45 + return;
1.46 + }
1.47 +
1.48 + // isCode(GetFlags(pAddress)) == Opcode
1.49 + // isTail(GetFlags(pAddress)) == Operand
1.50 + // ((GetFlags(pAddress) & MS_CODE) == FF_IMMD) == :iiam:
1.51 +
1.52 + auto bDone = 0;
1.53 +
1.54 + if (pInfo.n == 1)
1.55 + {
1.56 + if (pInfo.Op0.type == o_near || pInfo.Op0.type == o_far)
1.57 + {
1.58 + sig = sprintf("%s%02X %s", sig, Byte(pAddress), PrintWildcards(GetDTSize(pInfo.Op0.dtyp)));
1.59 + bDone = 1;
1.60 + }
1.61 + }
1.62 +
1.63 + if (!bDone) { // unknown, just wildcard addresses
1.64 + auto i;
1.65 + for (i = 0; i < pInfo.size; i++)
1.66 + {
1.67 + auto pLoc = pAddress + i;
1.68 + if (GetFixupTgtType(pLoc) == FIXUP_OFF32)
1.69 + {
1.70 + sig = sprintf("%s%s", sig, PrintWildcards(4));
1.71 + i = i + 3;
1.72 + } else {
1.73 + sig = sprintf("%s%02X ", sig, Byte(pLoc));
1.74 + }
1.75 + }
1.76 + }
1.77 +
1.78 + if (IsGoodSig(sig))
1.79 + break;
1.80 +
1.81 + pAddress = NextHead(pAddress, pFunctionEnd);
1.82 + }
1.83 +
1.84 + Message("%s\n", sig);
1.85 +
1.86 + SetStatus(IDA_STATUS_READY);
1.87 + return;
1.88 +}
1.89 +
1.90 +static GetDTSize(dtyp)
1.91 +{
1.92 + if (dtyp == dt_byte)
1.93 + {
1.94 + return 1;
1.95 + } else if (dtyp == dt_word) {
1.96 + return 2;
1.97 + } else if (dtyp == dt_dword) {
1.98 + return 4;
1.99 + } else if (dtyp == dt_float) {
1.100 + return 4;
1.101 + } else if (dtyp == dt_double) {
1.102 + return 8;
1.103 + } else {
1.104 + Warning("Unknown type size (%d)", dtyp);
1.105 + return -1;
1.106 + }
1.107 +}
1.108 +
1.109 +static PrintWildcards(count)
1.110 +{
1.111 + auto i, string;
1.112 + for (i = 0; i < count; i++)
1.113 + {
1.114 + string = sprintf("%s? ", string);
1.115 + }
1.116 + return string;
1.117 +}
1.118 +
1.119 +static IsGoodSig(sig)
1.120 +{
1.121 + auto count, addr;
1.122 + addr = FindBinary(addr, SEARCH_DOWN|SEARCH_NEXT, sig);
1.123 + while (addr != BADADDR)
1.124 + {
1.125 + count = count + 1;
1.126 + addr = FindBinary(addr, SEARCH_DOWN|SEARCH_NEXT, sig);
1.127 + }
1.128 + return (count == 1);
1.129 +}
1.130 \ No newline at end of file
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/tools/ida_scripts/vtable_dump.py Sun Jul 29 02:51:50 2012 +0100
2.3 @@ -0,0 +1,120 @@
2.4 +"""vtable_dump.py: IDAPython script to dump a linux vtable (and a reconstructed windows one) from a binary."""
2.5 +
2.6 +"""
2.7 +This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
2.8 +
2.9 +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
2.10 +
2.11 +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2.12 +
2.13 +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
2.14 +
2.15 +3. This notice may not be removed or altered from any source distribution.
2.16 +"""
2.17 +
2.18 +__author__ = "Asher Baker"
2.19 +__copyright__ = "Copyright 2012, Asher Baker"
2.20 +__license__ = "zlib/libpng"
2.21 +
2.22 +import re
2.23 +
2.24 +def Analyze():
2.25 + SetStatus(IDA_STATUS_WORK)
2.26 +
2.27 + if GetLongPrm(INF_COMPILER).id != COMP_GNU:
2.28 + Warning("This script is for binaries compiled with GCC only.")
2.29 + SetStatus(IDA_STATUS_READY)
2.30 + return
2.31 +
2.32 + ea = ScreenEA()
2.33 +
2.34 + if not isHead(GetFlags(ea)):
2.35 + ea = PrevHead(ea)
2.36 +
2.37 + # Param needed to support old IDAPython versions
2.38 + end = NextHead(ea, 4294967295)
2.39 +
2.40 + name = Demangle(Name(ea), GetLongPrm(INF_LONG_DN))
2.41 + if ea == BADADDR or name is None or not re.search(r"vf?table(?: |'\{)for", name):
2.42 + Warning("No vtable selected!\nSelect vtable block first.")
2.43 + SetStatus(IDA_STATUS_READY)
2.44 + return
2.45 +
2.46 + linux_vtable = []
2.47 + temp_windows_vtable = []
2.48 +
2.49 + # Extract vtable
2.50 + while ea < end:
2.51 + offset = Dword(ea)
2.52 +
2.53 + # A vtable starts with some metadata, if it's missing...
2.54 + if isCode(GetFlags(offset)):
2.55 + Warning("Something went wrong!")
2.56 + SetStatus(IDA_STATUS_READY)
2.57 + return
2.58 +
2.59 + # Skip thisoffs and typeinfo address
2.60 + ea += 8
2.61 +
2.62 + while ea < end and isCode(GetFlags(Dword(ea))):
2.63 + name = Demangle(Name(Dword(ea)), GetLongPrm(INF_LONG_DN))
2.64 +
2.65 + if offset == 0:
2.66 + linux_vtable.append(name)
2.67 + temp_windows_vtable.append(name)
2.68 + else:
2.69 + # MI entry, strip "`non-virtual thunk to'" and remove from list
2.70 + # But not if it's a dtor... what the hell is this.
2.71 + if (name.find("`non-virtual thunk to'") != -1) and name.find("::~") == -1:
2.72 + name = name[22:]
2.73 + #print "Stripping '%s' from windows vtable." % (name)
2.74 + temp_windows_vtable.remove(name)
2.75 +
2.76 + ea += 4
2.77 +
2.78 + for i, v in enumerate(temp_windows_vtable):
2.79 + if v.find("::~") != -1:
2.80 + #print "Found destructor at index %d: %s" % (i, v)
2.81 + del temp_windows_vtable[i]
2.82 + break
2.83 +
2.84 + windows_vtable = []
2.85 + overload_stack = []
2.86 + prev_function = ""
2.87 + prev_symbol = ""
2.88 + for v in temp_windows_vtable:
2.89 + function = v.split("(", 1)[0]
2.90 +
2.91 + if function == prev_function:
2.92 + # If we don't have a stack, we need to push the last function on first
2.93 + if len(overload_stack) == 0:
2.94 + # We will have added this in the previous run, remove it again...
2.95 + windows_vtable.pop()
2.96 + #print "Storing '%s' (!)" % (prev_symbol)
2.97 + overload_stack.append(prev_symbol)
2.98 + #print "Storing '%s'" % (v)
2.99 + overload_stack.append(v)
2.100 + else:
2.101 + # If we've moved onto something new, dump the stack first
2.102 + if len(overload_stack) > 0:
2.103 + #print overload_stack
2.104 + while len(overload_stack) > 0:
2.105 + windows_vtable.append(overload_stack.pop())
2.106 +
2.107 + windows_vtable.append(v)
2.108 +
2.109 + prev_function = function
2.110 + prev_symbol = v
2.111 +
2.112 + print "Lin Win Function"
2.113 + for i, v in enumerate(linux_vtable):
2.114 + winindex = windows_vtable.index(v) if v in windows_vtable else None
2.115 + if winindex is not None:
2.116 + print "%3d %3d %s" % (i, winindex, v)
2.117 + else:
2.118 + print "%3d %s" % (i, v)
2.119 +
2.120 + SetStatus(IDA_STATUS_READY)
2.121 +
2.122 +if __name__ == '__main__':
2.123 + Analyze()
2.124 \ No newline at end of file