Newer
Older
StdlibLibraryFuncNames.insert("div");
StdlibLibraryFuncNames.insert("labs");
StdlibLibraryFuncNames.insert("ldiv");
StdlibLibraryFuncNames.insert("mblen");
StdlibLibraryFuncNames.insert("mbtowc");
StdlibLibraryFuncNames.insert("wctomb");
StdlibLibraryFuncNames.insert("mbstowcs");
StdlibLibraryFuncNames.insert("wcstombs");
// Add special functions often inserted by gcc.
StdlibLibraryFuncNames.insert("stack_chk_fail");
Clark Coleman
committed
// Funcs with buffers as arguments; could analyze static size of buffers.
BufferArgLibraryFuncNames.insert("strcpy");
Clark Coleman
committed
BufferArgLibraryFuncNames.insert("strcpy_chk"); // GNU safer version, but crashes on error
Clark Coleman
committed
BufferArgLibraryFuncNames.insert("memcpy");
BufferArgLibraryFuncNames.insert("memmove");
BufferArgLibraryFuncNames.insert("strcat");
BufferArgLibraryFuncNames.insert("strcmp");
return;
} // end of InitLibraryFuncNames()
bool IsMathLibraryFunc(string CalleeName) {
set<string>::const_iterator FuncIter = MathLibraryFuncNames.find(CalleeName);
return (FuncIter != MathLibraryFuncNames.cend());
}
bool IsStdioLibraryFunc(string CalleeName) {
set<string>::const_iterator FuncIter = StdioLibraryFuncNames.find(CalleeName);
return (FuncIter != StdioLibraryFuncNames.cend());
}
bool IsStdlibLibraryFunc(string CalleeName) {
set<string>::const_iterator FuncIter = StdlibLibraryFuncNames.find(CalleeName);
return (FuncIter != StdlibLibraryFuncNames.cend());
}
Clark Coleman
committed
// Is FuncName a function that operates on buffers that might be of analyzeable buffer length?
bool IsBufferArgFuncName(const string CalleeName) {
set<string>::const_iterator FuncIter = BufferArgLibraryFuncNames.find(CalleeName);
return (FuncIter != BufferArgLibraryFuncNames.cend());
}
// Utility to count bits set in an unsigned int, e.g. ArgPosBits.
unsigned int CountBitsSet(unsigned int ArgPosBits) {
unsigned int count; // count accumulates the total bits set in ArgPosBits
for (count = 0; ArgPosBits; ++count) {
ArgPosBits &= (ArgPosBits - 1); // clear the least significant bit set
}
// Brian Kernighan's method goes through as many iterations as there are set bits.
// So if we have a 32-bit word with only the high bit set, then it will only go once through the loop.
// Published in 1988, the C Programming Language 2nd Ed. (by Brian W. Kernighan and Dennis M. Ritchie) mentions this in exercise 2-9.
// On April 19, 2006 Don Knuth pointed out to me that this method "was first published by Peter Wegner in CACM 3 (1960), 322.
// (Also discovered independently by Derrick Lehmer and published in 1964 in a book edited by Beckenbach.)"
return count;
}
// Utility to get highest bit set in a byte, numbered 0 (lowest) to 7 (highest).
unsigned int HighestBitSet(uint8_t Byte) {
unsigned int RetVal = 0;
if (Byte & 0xf0) { // check upper 4 bits
RetVal |= 4; // at least bit 4 or higher is set
Byte >>= 4; // shift upper nibble to lower nibble
}
if (Byte & 0xc) { // check upper two bits of lower nibble
RetVal |= 2; // At least bit 2 or higher is set
Byte >>= 2; // shift upper two bits of lower nibble into lowest two bits
}
if (Byte & 0x2) { // Check second least significant bit
RetVal |= 1;
}
return RetVal;
} // end of HighestBitSet()
// Utility to get lowest bit set in a byte, numbered 0 (lowest) to 7 (highest).
unsigned int LowestBitSet(unsigned char Byte) {
unsigned int RetVal = 0;
if (Byte & 0x03) { // check lower 2 bits
RetVal = (Byte & 1) ? 0 : 1;
}
else if (Byte & 0x0c) { // check upper two bits of lower nibble
RetVal = (Byte & 4) ? 2 : 3;
}
else if (Byte & 0x30) { // Check lower two bits of upper nibble
RetVal = (Byte & 16) ? 4 : 5;
}
else {
assert(Byte & 0xc0);
RetVal = (Byte & 64) ? 6 : 7;
}
return RetVal;
}
// Utility to get highest bit set in an uint32_t, numbered 0 (lowest) to 31 (highest).
// Assumes that UintVal is non-zero and has some bit set.
unsigned int HighestBitSetInUint(uint32_t UintVal) {
unsigned int RetVal = 0;
uint8_t Byte0 = UintVal & 0xff;
uint8_t Byte1 = UintVal & 0xff00;
uint8_t Byte2 = UintVal & 0xff0000;
uint8_t Byte3 = UintVal & 0xff000000;
if (Byte3 > 0) {
RetVal = HighestBitSet(Byte3) + 24;
}
else if (Byte2 > 0) {
RetVal = HighestBitSet(Byte2) + 16;
}
else if (Byte1 > 0) {
RetVal = HighestBitSet(Byte1) + 8;
}
else if (Byte0 > 0) {
RetVal = HighestBitSet(Byte0);
}
return RetVal;
} // end of HighestBitSetInUint()
// Initialize the FG info for the return register from any library function
// whose name implies that we know certain return values (e.g. atoi() returns
// a signed integer, while strtoul() returns an unsigned long).
void GetLibFuncFGInfo(string FuncName, struct FineGrainedInfo &InitFGInfo) {
map<string, struct FineGrainedInfo>::iterator FindIter;
FindIter = ReturnRegisterTypeMap.find(FuncName);
if (FindIter == ReturnRegisterTypeMap.end()) { // not found
InitFGInfo.SignMiscInfo = 0;
InitFGInfo.SizeInfo = 0;
}
else { // found
InitFGInfo = FindIter->second;
}
return;
} // end of GetLibFuncFGInfo()
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
// Is FuncName a standard library function name?
bool IsLibFuncName(std::string CalleeName) {
// Return true if we find the name in any of our function type maps.
map<string, struct FineGrainedInfo>::iterator RetTypeIter = ReturnRegisterTypeMap.find(CalleeName);
if (RetTypeIter != ReturnRegisterTypeMap.end()) { // found
return true;
}
map<string, unsigned int>::iterator PtrArgIter = PointerArgPositionMap.find(CalleeName);
if (PtrArgIter != PointerArgPositionMap.end()) { // found it
return true;
}
map<string, unsigned int>::iterator TaintIter = TaintWarningArgPositionMap.find(CalleeName);
if (TaintIter != TaintWarningArgPositionMap.end()) { // found it
return true;
}
map<string, unsigned int>::iterator UnsignedIter = UnsignedArgPositionMap.find(CalleeName);
if (UnsignedIter != UnsignedArgPositionMap.end()) { // found it
return true;
}
map<string, string>::iterator SinkIter = IntegerErrorCallSinkMap.find(CalleeName);
if (SinkIter != IntegerErrorCallSinkMap.end()) { // found it
return true;
}
// Put searches for additional library function names here.
if (0 == CalleeName.compare("setuid")) {
return true;
}
else if (IsStdioLibraryFunc(CalleeName)) {
return true;
}
else if (IsMathLibraryFunc(CalleeName)) {
return true;
}
else if (IsStdlibLibraryFunc(CalleeName)) {
return true;
}
return false;
} // end of IsLibFuncName()
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
// Is FuncName a startup func called before main(), or a wrapup function called by the system?
bool IsStartupFuncName(const std::string FuncName) {
bool NameMatched = false;
char IDA_func_name[STARS_MAXSTR];
std::size_t SkipCount;
SkipCount = strspn(FuncName.c_str(), "._");
std::string TempFuncName = FuncName.substr(SkipCount); // remove leading periods and underscores
if (0 == TempFuncName.compare("init_proc")) {
NameMatched = true;
}
else if (0 == TempFuncName.compare("init")) {
NameMatched = true;
}
else if (0 == TempFuncName.compare("start")) {
NameMatched = true;
}
else if (0 == TempFuncName.compare("gmon_start")) {
NameMatched = true;
}
else if (0 == TempFuncName.compare("call_gmon_start")) {
NameMatched = true;
}
else if (0 == TempFuncName.compare("libc_start_main")) {
NameMatched = true;
}
else if (0 == TempFuncName.compare("call_gmon_start__")) {
NameMatched = true;
}
else if (0 == TempFuncName.compare("libc_start_main__")) {
NameMatched = true;
}
else if (0 == TempFuncName.compare("libc_csu_init")) {
NameMatched = true;
}
else if (0 == TempFuncName.compare("libc_csu_fini")) {
NameMatched = true;
}
else if (0 == TempFuncName.compare("do_global_dtors_aux")) {
NameMatched = true;
}
else if (0 == TempFuncName.compare("term_proc")) {
NameMatched = true;
}
clc5q
committed
else if (0 == TempFuncName.compare("fini")) {
NameMatched = true;
}
else if (0 == TempFuncName.compare("frame_dummy")) {
NameMatched = true;
}
return NameMatched;
}