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