tools/ida_scripts/makesig.idc
changeset 3590 6908e80a69af
     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