Files
int2ssl/ProcTable.cpp
T

317 lines
8.4 KiB
C++
Raw Normal View History

2015-02-15 18:53:04 +03:00
/**
*
* Copyright (c) 2005-2009 Anchorite (TeamX), <anchorite2001@yandex.ru>
2015-02-15 21:33:27 +03:00
* Copyright (c) 2014-2015 Nirran, phobos2077
* Copyright (c) 2015 alexeevdv <mail@alexeevdv.ru>
2015-02-15 18:53:04 +03:00
* Distributed under the GNU GPL v3. For full terms see the file license.txt
*
*/
// C++ standard includes
#include <iostream>
2015-02-16 00:30:55 +03:00
#include <fstream>
2015-02-15 21:30:47 +03:00
#include <vector>
2015-02-15 22:27:31 +03:00
#include <cstdlib>
2015-02-16 00:30:55 +03:00
#include <algorithm>
2015-02-15 18:53:04 +03:00
// int2ssl includes
2015-02-13 16:59:11 +03:00
#include "ProcTable.h"
#include "Utility.h"
#include "ObjectAttributes.h"
2015-02-15 18:53:04 +03:00
// Third party includes
2015-02-13 16:59:11 +03:00
2015-02-16 00:30:55 +03:00
extern std::ifstream g_ifstream;
extern std::ofstream g_ofstream;
2015-02-13 16:59:11 +03:00
CProcDescriptor::CProcDescriptor() :
2015-02-14 13:39:47 +03:00
m_ulNameOffset(0),
m_ulType(0),
m_ulTime(0),
m_ulExpressionOffset(0),
m_ulBodyOffset(0),
m_ulNumArgs(0)
2015-02-13 16:59:11 +03:00
{
}
CProcDescriptor::CProcDescriptor(const CProcDescriptor& Item) :
2015-02-14 13:39:47 +03:00
m_ulNameOffset(Item.m_ulNameOffset),
m_ulType(Item.m_ulType),
m_ulTime(Item.m_ulTime),
m_ulExpressionOffset(Item.m_ulExpressionOffset),
m_ulBodyOffset(Item.m_ulBodyOffset),
m_ulNumArgs(Item.m_ulNumArgs)
2015-02-13 16:59:11 +03:00
{
}
CProcDescriptor::~CProcDescriptor()
{
}
CProcDescriptor& CProcDescriptor::operator = (const CProcDescriptor& Item)
{
2015-02-14 14:38:14 +03:00
if (&Item != this)
{
2015-02-14 13:39:47 +03:00
m_ulNameOffset = Item.m_ulNameOffset;
m_ulType = Item.m_ulType;
m_ulTime = Item.m_ulTime;
m_ulExpressionOffset = Item.m_ulExpressionOffset;
m_ulBodyOffset = Item.m_ulBodyOffset;
m_ulNumArgs = Item.m_ulNumArgs;
}
2015-02-13 16:59:11 +03:00
2015-02-14 13:39:47 +03:00
return (*this);
2015-02-13 16:59:11 +03:00
}
2015-02-16 00:30:55 +03:00
void CProcDescriptor::Serialize()
2015-02-13 16:59:11 +03:00
{
2015-02-14 14:38:14 +03:00
2015-02-16 00:30:55 +03:00
g_ifstream.read((char*)&m_ulNameOffset, sizeof(m_ulNameOffset));
std::reverse((char*)&m_ulNameOffset, (char*)&m_ulNameOffset + sizeof(m_ulNameOffset));
g_ifstream.read((char*)&m_ulType, sizeof(m_ulType));
std::reverse((char*)&m_ulType, (char*)&m_ulType + sizeof(m_ulType));
g_ifstream.read((char*)&m_ulTime, sizeof(m_ulTime));
std::reverse((char*)&m_ulTime, (char*)&m_ulTime + sizeof(m_ulTime));
g_ifstream.read((char*)&m_ulExpressionOffset, sizeof(m_ulExpressionOffset));
std::reverse((char*)&m_ulExpressionOffset, (char*)&m_ulExpressionOffset + sizeof(m_ulExpressionOffset));
g_ifstream.read((char*)&m_ulBodyOffset, sizeof(m_ulBodyOffset));
std::reverse((char*)&m_ulBodyOffset, (char*)&m_ulBodyOffset + sizeof(m_ulBodyOffset));
g_ifstream.read((char*)&m_ulNumArgs, sizeof(m_ulNumArgs));
std::reverse((char*)&m_ulNumArgs, (char*)&m_ulNumArgs + sizeof(m_ulNumArgs));
2015-02-14 14:38:14 +03:00
2015-02-16 00:30:55 +03:00
if (!g_ifstream)
2015-02-13 16:59:11 +03:00
{
2015-02-16 00:30:55 +03:00
std::cout << "Error: Unable read procedure descriptor" << std::endl;
2015-02-15 19:14:18 +03:00
throw std::exception();
2015-02-14 13:39:47 +03:00
}
2015-02-13 16:59:11 +03:00
}
2015-02-16 00:30:55 +03:00
void CProcDescriptor::Dump()
2015-02-13 16:59:11 +03:00
{
2015-02-15 16:16:45 +03:00
std::string strType;
2015-02-13 16:59:11 +03:00
2015-02-13 22:31:52 +03:00
if (m_ulType != 0x00000000)
{
2015-02-14 13:39:47 +03:00
strType = "( ";
2015-02-13 16:59:11 +03:00
2015-02-13 22:31:52 +03:00
if (m_ulType & P_TIMED)
{
2015-02-14 13:39:47 +03:00
strType += "timed ";
}
2015-02-13 16:59:11 +03:00
2015-02-13 22:31:52 +03:00
if (m_ulType & P_CONDITIONAL)
{
2015-02-14 13:39:47 +03:00
strType += "conditional ";
}
2015-02-13 16:59:11 +03:00
2015-02-13 22:31:52 +03:00
if (m_ulType & P_IMPORT)
{
2015-02-14 13:39:47 +03:00
strType += "import ";
}
2015-02-13 16:59:11 +03:00
2015-02-14 13:39:47 +03:00
if (m_ulType & P_EXPORT) {
strType += "export ";
}
2015-02-13 16:59:11 +03:00
2015-02-14 13:39:47 +03:00
if (m_ulType & P_CRITICAL) {
strType += "critical ";
}
2015-02-13 16:59:11 +03:00
2015-02-14 13:39:47 +03:00
strType += ")";
}
2015-02-14 14:38:14 +03:00
else
{
2015-02-14 13:39:47 +03:00
strType = "No special types";
}
2015-02-13 16:59:11 +03:00
2015-02-16 00:30:55 +03:00
g_ofstream << format("Name offset: 0x%08X", m_ulNameOffset) << std::endl;
g_ofstream << format("Type: 0x%08X // %s", m_ulType, strType.c_str()) << std::endl;
g_ofstream << format("Time: 0x%08X // %d", m_ulTime, m_ulTime) << std::endl;
g_ofstream << format("Expression offset: 0x%08X", m_ulExpressionOffset) << std::endl;
g_ofstream << format("Body offset: 0x%08X", m_ulBodyOffset) << std::endl;
g_ofstream << format("Number of args: 0x%08X // %d", m_ulNumArgs, m_ulNumArgs) << std::endl;
2015-02-13 16:59:11 +03:00
}
CProcTable::CProcTable()
{
}
CProcTable::~CProcTable()
{
}
struct ProcBodyOffset {
2015-02-15 18:28:27 +03:00
uint32_t m_ulProcIndex;
uint32_t m_ulBodyOffset;
2015-02-13 16:59:11 +03:00
};
int compareProcBodyOffsets(const void* elem0, const void* elem1)
{
2015-02-14 13:39:47 +03:00
ProcBodyOffset offset0 = *((ProcBodyOffset*)elem0);
ProcBodyOffset offset1 = *((ProcBodyOffset*)elem1);
2015-02-13 16:59:11 +03:00
2015-02-14 14:38:14 +03:00
if (offset0.m_ulBodyOffset < offset1.m_ulBodyOffset)
{
2015-02-14 13:39:47 +03:00
return -1;
}
2015-02-14 14:38:14 +03:00
else if (offset0.m_ulBodyOffset > offset1.m_ulBodyOffset)
{
2015-02-14 13:39:47 +03:00
return 1;
}
2015-02-14 14:38:14 +03:00
else
{
if (offset0.m_ulProcIndex < offset1.m_ulProcIndex)
{
2015-02-14 13:39:47 +03:00
return -1;
}
2015-02-14 14:38:14 +03:00
else if (offset0.m_ulProcIndex > offset1.m_ulProcIndex)
{
2015-02-14 13:39:47 +03:00
return 1;
}
2015-02-14 14:38:14 +03:00
else
{
2015-02-14 13:39:47 +03:00
return 0;
}
}
2015-02-13 16:59:11 +03:00
}
2015-02-16 00:30:55 +03:00
void CProcTable::Serialize()
2015-02-13 16:59:11 +03:00
{
2015-02-15 21:30:47 +03:00
m_Table.clear();
m_ProcSize.clear();
2015-02-14 14:38:14 +03:00
2015-02-16 00:30:55 +03:00
uint32_t oldPosition = g_ifstream.tellg();
g_ifstream.seekg(0, std::ios_base::end);
uint32_t ulSizeOfFile = g_ifstream.tellg();
g_ifstream.seekg(oldPosition, std::ios_base::beg);
2015-02-15 18:28:27 +03:00
uint32_t ulSizeOfTable;
2015-02-16 00:30:55 +03:00
g_ifstream.read((char*)&ulSizeOfTable, sizeof(ulSizeOfTable));
std::reverse((char*)&ulSizeOfTable, (char*)&ulSizeOfTable + sizeof(ulSizeOfTable));
2015-02-14 14:38:14 +03:00
2015-02-16 00:30:55 +03:00
if (!g_ifstream)
2015-02-13 16:59:11 +03:00
{
2015-02-14 14:38:14 +03:00
printf("Error: Unable read size of procedures table\n");
2015-02-15 19:14:18 +03:00
throw std::exception();
2015-02-14 13:39:47 +03:00
}
2015-02-13 16:59:11 +03:00
2015-02-15 21:30:47 +03:00
m_Table.resize(ulSizeOfTable);
m_ProcSize.resize(ulSizeOfTable);
2015-02-13 16:59:11 +03:00
2015-02-15 18:28:27 +03:00
uint32_t ulIndexOfProcOffset = 0;
2015-02-14 14:38:14 +03:00
ProcBodyOffset* pOffsets = new ProcBodyOffset[ulSizeOfTable + 1];
2015-02-13 16:59:11 +03:00
2015-02-14 14:38:14 +03:00
if (pOffsets == NULL)
{
2015-02-15 19:14:18 +03:00
throw std::exception();
2015-02-14 14:38:14 +03:00
}
2015-02-13 16:59:11 +03:00
2015-02-15 18:28:27 +03:00
for(uint32_t i = 0; i < ulSizeOfTable; i++)
2015-02-14 14:38:14 +03:00
{
// printf("======== %u =========\n", i);
2015-02-16 00:30:55 +03:00
m_Table[i].Serialize();
2015-02-14 23:18:15 +03:00
m_ProcSize[i] = 0; // Initialize size of procedure
2015-02-14 14:38:14 +03:00
2015-02-14 23:18:15 +03:00
if (!(m_Table[i].m_ulType & P_IMPORT))
2015-02-13 22:31:52 +03:00
{
2015-02-14 23:18:15 +03:00
if ((m_Table[i].m_ulBodyOffset != 0) && (m_Table[i].m_ulBodyOffset != ulSizeOfFile))
2015-02-14 14:38:14 +03:00
{
pOffsets[ulIndexOfProcOffset].m_ulProcIndex = i;
2015-02-14 23:18:15 +03:00
pOffsets[ulIndexOfProcOffset].m_ulBodyOffset = m_Table[i].m_ulBodyOffset;
2015-02-14 14:38:14 +03:00
ulIndexOfProcOffset++;
}
else
{
2015-02-14 23:18:15 +03:00
m_Table[i].m_ulType |= P_NOTIMPLEMENTED;
2015-02-14 14:38:14 +03:00
}
}
}
pOffsets[ulIndexOfProcOffset].m_ulProcIndex = ulIndexOfProcOffset + 1;
pOffsets[ulIndexOfProcOffset].m_ulBodyOffset = ulSizeOfFile;
qsort(pOffsets, ulIndexOfProcOffset, sizeof(ProcBodyOffset), compareProcBodyOffsets);
// Sizes of procedures
2015-02-15 18:28:27 +03:00
for(uint32_t i = 0; i < ulIndexOfProcOffset; i++)
2015-02-14 14:38:14 +03:00
{
if (pOffsets[i + 1].m_ulBodyOffset >= pOffsets[i].m_ulBodyOffset)
{
2015-02-14 23:18:15 +03:00
m_ProcSize[pOffsets[i].m_ulProcIndex] = pOffsets[i + 1].m_ulBodyOffset - pOffsets[i].m_ulBodyOffset;
2015-02-14 14:38:14 +03:00
}
else
{
printf("Error: Procedures are not sorted in ascending address order\n");
2015-02-15 19:14:18 +03:00
throw std::exception();
2015-02-14 13:39:47 +03:00
}
}
2015-02-14 14:38:14 +03:00
delete [] pOffsets;
2015-02-15 18:28:27 +03:00
for(uint32_t i = 0; i < ulSizeOfTable; i++)
2015-02-14 14:38:14 +03:00
{
2015-02-14 23:18:15 +03:00
if (m_Table[i].m_ulBodyOffset != 0)
2015-02-14 14:38:14 +03:00
{
2015-02-14 23:18:15 +03:00
m_ulOffsetOfProcSection = m_Table[i].m_ulBodyOffset;
2015-02-14 14:38:14 +03:00
break;
}
}
// // For debugging only
// printf("Total: %d\n", m_Table.GetSize());
// for(i = 0; i < ulSizeOfTable; i++)
// {
2015-02-14 23:18:15 +03:00
// printf("Offset: 0x%08X, size: 0x%08X\n", m_Table[i].m_ulBodyOffset, m_ProcSize[i]);
2015-02-14 14:38:14 +03:00
// }
// printf("m_ulOffsetOfProcSection: 0x%08X\n", m_ulOffsetOfProcSection);
2015-02-13 16:59:11 +03:00
}
2015-02-15 22:27:31 +03:00
uint32_t CProcTable::GetSize()
2015-02-13 16:59:11 +03:00
{
2015-02-15 21:30:47 +03:00
return m_Table.size();
2015-02-13 16:59:11 +03:00
}
2015-02-15 22:55:52 +03:00
uint32_t CProcTable::GetSizeOfProc(uint32_t nIndex)
2015-02-13 16:59:11 +03:00
{
2015-02-15 22:55:52 +03:00
if (nIndex >= m_ProcSize.size())
2015-02-14 14:38:14 +03:00
{
2015-02-14 13:39:47 +03:00
printf("Warning: Invalid index of procedure (%d). Exception will be thrown\n", nIndex);
2015-02-15 19:14:18 +03:00
throw std::exception();
2015-02-14 13:39:47 +03:00
}
2015-02-13 16:59:11 +03:00
2015-02-14 23:18:15 +03:00
return m_ProcSize[nIndex];
2015-02-13 16:59:11 +03:00
}
2015-02-15 18:28:27 +03:00
uint32_t CProcTable::GetOffsetOfProcSection()
2015-02-13 16:59:11 +03:00
{
2015-02-14 13:39:47 +03:00
return m_ulOffsetOfProcSection;
2015-02-13 16:59:11 +03:00
}
2015-02-16 00:30:55 +03:00
void CProcTable::Dump()
2015-02-13 16:59:11 +03:00
{
2015-02-15 21:30:47 +03:00
for(unsigned int i = 0; i < m_Table.size(); i++)
2015-02-13 22:31:52 +03:00
{
2015-02-16 00:30:55 +03:00
g_ofstream << format("======== Procedure %d ========", i) << std::endl;
m_Table[i].Dump();
g_ofstream << std::endl;
2015-02-14 13:39:47 +03:00
}
2015-02-13 16:59:11 +03:00
}
2015-02-15 22:55:52 +03:00
CProcDescriptor& CProcTable::operator [] (uint32_t nIndex)
2015-02-13 16:59:11 +03:00
{
2015-02-15 22:55:52 +03:00
if (nIndex >= m_ProcSize.size())
2015-02-14 14:38:14 +03:00
{
2015-02-14 13:39:47 +03:00
printf("Warning: Invalid index of procedure (%d). Exception will be thrown\n", nIndex);
2015-02-15 19:14:18 +03:00
throw std::exception();
2015-02-14 13:39:47 +03:00
}
2015-02-13 16:59:11 +03:00
2015-02-14 23:18:15 +03:00
return m_Table[nIndex];
2015-02-13 16:59:11 +03:00
}