#include /* makesig.idc: IDA script to automatically create and wildcard a function signature. * Copyright 2012, Asher Baker * * 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. * * 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. 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. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source distribution. */ static main() { Wait(); // We won't work until autoanalysis is complete SetStatus(IDA_STATUS_WORK); auto pAddress = ScreenEA(); pAddress = GetFunctionAttr(pAddress, FUNCATTR_START); if (pAddress == BADADDR) { Warning("Make sure you are in a function!"); SetStatus(IDA_STATUS_READY); return; } auto sig; auto pFunctionEnd = GetFunctionAttr(pAddress, FUNCATTR_END); while (pAddress != BADADDR) { auto pInfo = DecodeInstruction(pAddress); if (!pInfo) { Warning("Something went terribly wrong D:"); SetStatus(IDA_STATUS_READY); return; } // isCode(GetFlags(pAddress)) == Opcode // isTail(GetFlags(pAddress)) == Operand // ((GetFlags(pAddress) & MS_CODE) == FF_IMMD) == :iiam: auto bDone = 0; if (pInfo.n == 1) { if (pInfo.Op0.type == o_near || pInfo.Op0.type == o_far) { sig = sprintf("%s%02X %s", sig, Byte(pAddress), PrintWildcards(GetDTSize(pInfo.Op0.dtyp))); bDone = 1; } } if (!bDone) { // unknown, just wildcard addresses auto i; for (i = 0; i < pInfo.size; i++) { auto pLoc = pAddress + i; if (GetFixupTgtType(pLoc) == FIXUP_OFF32) { sig = sprintf("%s%s", sig, PrintWildcards(4)); i = i + 3; } else { sig = sprintf("%s%02X ", sig, Byte(pLoc)); } } } if (IsGoodSig(sig)) break; pAddress = NextHead(pAddress, pFunctionEnd); } Message("%s\n", sig); SetStatus(IDA_STATUS_READY); return; } static GetDTSize(dtyp) { if (dtyp == dt_byte) { return 1; } else if (dtyp == dt_word) { return 2; } else if (dtyp == dt_dword) { return 4; } else if (dtyp == dt_float) { return 4; } else if (dtyp == dt_double) { return 8; } else { Warning("Unknown type size (%d)", dtyp); return -1; } } static PrintWildcards(count) { auto i, string; for (i = 0; i < count; i++) { string = sprintf("%s? ", string); } return string; } static IsGoodSig(sig) { auto count, addr; addr = FindBinary(addr, SEARCH_DOWN|SEARCH_NEXT, sig); while (addr != BADADDR) { count = count + 1; addr = FindBinary(addr, SEARCH_DOWN|SEARCH_NEXT, sig); } return (count == 1); }