1+ #include " stdafx.h"
2+ #include " TreeImportExport.h"
3+ #include " Architecture.h"
4+ #include < Helpers.h>
5+
6+ TreeImportExport::TreeImportExport (const WCHAR* pTargetXmlFile){
7+ wcscpy_s (_xmlPath, pTargetXmlFile);
8+ }
9+
10+ bool TreeImportExport::ExportTreeList (const std::map<DWORD_PTR, ImportModuleThunk>& moduleThunk, const std::string processName,
11+ DWORD_PTR oep, DWORD_PTR iat, DWORD iatSize){
12+ // 定义doc对象
13+ tinyxml2::XMLDocument doc;
14+ // 增加xml文档声明
15+ tinyxml2::XMLDeclaration* pDecl = doc.NewDeclaration ();
16+ doc.LinkEndChild (pDecl);
17+
18+ // 添加节点
19+ tinyxml2::XMLElement* pRootElement = doc.NewElement (" target" );
20+
21+ SetTargetInformation (pRootElement, processName, oep, iat, iatSize);
22+ AddModuleListToRootElement (pRootElement, moduleThunk);
23+
24+ doc.LinkEndChild (pRootElement);
25+
26+ return SaveXmlToFile (doc, _xmlPath);
27+ }
28+
29+ bool TreeImportExport::ImportTreeList (std::map<DWORD_PTR, ImportModuleThunk>& moduleThunk,
30+ DWORD_PTR* pOEP, DWORD_PTR* pIAT, DWORD* pSize) {
31+ moduleThunk.clear ();
32+ *pOEP = *pIAT = 0 ;
33+ *pSize = 0 ;
34+
35+ tinyxml2::XMLDocument doc;
36+ if (!ReadXmlFile (doc, _xmlPath)) {
37+ return false ;
38+ }
39+
40+ tinyxml2::XMLElement* pTargetElement = doc.FirstChildElement ();
41+ if (!pTargetElement) {
42+ return false ;
43+ }
44+
45+ *pOEP = ConvertStringToDwordPtr (pTargetElement->Attribute (" oep_va" ));
46+ *pIAT = ConvertStringToDwordPtr (pTargetElement->Attribute (" iat_va" ));
47+ *pSize = ConvertStringToDwordPtr (pTargetElement->Attribute (" iat_size" ));
48+
49+ ParseAllElementModules (pTargetElement, moduleThunk);
50+
51+ return true ;
52+ }
53+
54+ void TreeImportExport::SetTargetInformation (tinyxml2::XMLElement* pRootElement, std::string processName,
55+ DWORD_PTR oep, DWORD_PTR iat, DWORD iatSize) {
56+ pRootElement->SetAttribute (" process_name" , processName.c_str ());
57+
58+ ConvertDwordPtrToString (oep);
59+ pRootElement->SetAttribute (" oep_va" , _xmlStringBuffer);
60+
61+ ConvertDwordPtrToString (iat);
62+ pRootElement->SetAttribute (" iat_va" , _xmlStringBuffer);
63+
64+ ConvertDwordPtrToString (iatSize);
65+ pRootElement->SetAttribute (" iat_size" , _xmlStringBuffer);
66+ }
67+
68+ void TreeImportExport::AddModuleListToRootElement (tinyxml2::XMLElement* pRootElement,
69+ const std::map<DWORD_PTR, ImportModuleThunk>& moduleThunkMap){
70+
71+ for (auto & moduleThunk : moduleThunkMap) {
72+ const ImportModuleThunk& importModultThunk = moduleThunk.second ;
73+ tinyxml2::XMLElement* pModuleElement = GetModuleXmlElement (pRootElement,&importModultThunk);
74+
75+ for (auto & thunk : importModultThunk.m_ThunkMap ) {
76+ const ImportThunk& importThunk = thunk.second ;
77+ tinyxml2::XMLElement* pImportElement = GetImportXmlElement (pModuleElement, &importThunk);
78+ }
79+ }
80+ }
81+
82+
83+ void TreeImportExport::ParseAllElementModules (tinyxml2::XMLElement* pTargetElement,
84+ std::map<DWORD_PTR, ImportModuleThunk>& moduleThunkMap)
85+ {
86+ ImportModuleThunk importModuleThunk;
87+
88+ for (tinyxml2::XMLElement* pModuleElement = pTargetElement->FirstChildElement ();
89+ pModuleElement; pModuleElement = pModuleElement->NextSiblingElement ()) {
90+ std::string moduleName = pModuleElement->Attribute (" module_name" );
91+ if (!moduleName.empty ()) {
92+ importModuleThunk.m_FirstThunk = ConvertStringToDwordPtr (pModuleElement->Attribute (" first_thunk_rva" ));
93+ importModuleThunk.m_ThunkMap .clear ();
94+ ParseAllElementImports (pModuleElement, &importModuleThunk);
95+
96+ moduleThunkMap[importModuleThunk.m_FirstThunk ] = importModuleThunk;
97+ }
98+ }
99+ }
100+
101+ void TreeImportExport::ParseAllElementImports (tinyxml2::XMLElement* pModuleElement,
102+ ImportModuleThunk* pModuleThunk)
103+ {
104+ ImportThunk importThunk;
105+ for (tinyxml2::XMLElement* pImportElement = pModuleElement->FirstChildElement ();
106+ pImportElement; pImportElement = pImportElement->NextSiblingElement ()) {
107+ const char * pTemp = pImportElement->Value ();
108+ if (!strcmp (pTemp, " import_valid" )) {
109+ pTemp = pImportElement->Attribute (" name" );
110+ if (pTemp) {
111+ strcpy_s (importThunk.m_Name , pTemp);
112+ }
113+ else {
114+ importThunk.m_Name [0 ] = 0 ;
115+ }
116+
117+ wcscpy_s (importThunk.m_ModuleName , pModuleThunk->m_ModuleName );
118+
119+ importThunk.m_Suspect = ConvertStringToBool (pImportElement->Attribute (" suspect" ));
120+ importThunk.m_Ordinal = ConvertStringToWord (pImportElement->Attribute (" ordinal" ));
121+ importThunk.m_Hint = ConvertStringToWord (pImportElement->Attribute (" hint" ));
122+
123+ importThunk.m_Valid = true ;
124+ }
125+ else {
126+ importThunk.m_Valid = false ;
127+ importThunk.m_Suspect = true ;
128+ }
129+
130+ importThunk.m_ApiAddressVA = ConvertStringToDwordPtr (pImportElement->Attribute (" address_va" ));
131+ importThunk.m_RVA = ConvertStringToDwordPtr (pImportElement->Attribute (" iat_rva" ));
132+
133+ if (importThunk.m_RVA != 0 ) {
134+ pModuleThunk->m_ThunkMap [importThunk.m_RVA ] = importThunk;
135+ }
136+ }
137+ }
138+
139+ tinyxml2::XMLElement* TreeImportExport::GetModuleXmlElement (tinyxml2::XMLElement* pParentElement,
140+ const ImportModuleThunk* pModuleThunk)
141+ {
142+ tinyxml2::XMLElement* pModuleElement = pParentElement->InsertNewChildElement (" module" );
143+ std::string moduleName = Helpers::WstringToString (pModuleThunk->m_ModuleName );
144+ pModuleElement->SetAttribute (" module_name" , moduleName.c_str ());
145+
146+ ConvertDwordPtrToString (pModuleThunk->GetFirstThunk ());
147+ pModuleElement->SetAttribute (" first_thunk_rva" , _xmlStringBuffer);
148+
149+ return pModuleElement;
150+ }
151+
152+ tinyxml2::XMLElement* TreeImportExport::GetImportXmlElement (tinyxml2::XMLElement* pParentElement,
153+ const ImportThunk* pThunk)
154+ {
155+ tinyxml2::XMLElement* pImportElement = nullptr ;
156+ if (pThunk->m_Valid ) {
157+ pImportElement = pParentElement->InsertNewChildElement (" import_valid" );
158+ if (pThunk->m_Name [0 ] != ' \0 ' ) {
159+ pImportElement->SetAttribute (" name" , pThunk->m_Name );
160+ }
161+
162+ ConvertWordToString (pThunk->m_Ordinal );
163+ pImportElement->SetAttribute (" ordinal" , _xmlStringBuffer);
164+
165+ ConvertWordToString (pThunk->m_Hint );
166+ pImportElement->SetAttribute (" hint" , _xmlStringBuffer);
167+
168+ ConvertBoolToString (pThunk->m_Suspect );
169+ pImportElement->SetAttribute (" suspect" , _xmlStringBuffer);
170+ }
171+ else {
172+ pImportElement = pParentElement->InsertNewChildElement (" import_invalid" );
173+ }
174+
175+ ConvertDwordPtrToString (pThunk->m_RVA );
176+ pImportElement->SetAttribute (" iat_rva" , _xmlStringBuffer);
177+
178+ ConvertDwordPtrToString (pThunk->m_ApiAddressVA );
179+ pImportElement->SetAttribute (" address_va" , _xmlStringBuffer);
180+
181+ return pImportElement;
182+ }
183+
184+
185+ bool TreeImportExport::SaveXmlToFile (tinyxml2::XMLDocument& doc, const WCHAR* pXmlFilePath){
186+ std::string xmlFilePath = Helpers::WstringToString (pXmlFilePath);
187+ tinyxml2::XMLError error = doc.SaveFile (xmlFilePath.c_str ());
188+ return error == tinyxml2::XML_SUCCESS ? true : false ;
189+ }
190+
191+ bool TreeImportExport::ReadXmlFile (tinyxml2::XMLDocument& doc, const WCHAR* pXmlFilePath){
192+ std::string xmlFilePath = Helpers::WstringToString (pXmlFilePath);
193+ tinyxml2::XMLError error = doc.LoadFile (xmlFilePath.c_str ());
194+ return error == tinyxml2::XML_SUCCESS ? true : false ;
195+ }
196+
197+ void TreeImportExport::ConvertBoolToString (const bool value) {
198+ if (value) {
199+ strcpy_s (_xmlStringBuffer, " 1" );
200+ }
201+ else {
202+ strcpy_s (_xmlStringBuffer, " 0" );
203+ }
204+ }
205+
206+ void TreeImportExport::ConvertWordToString (const WORD value)
207+ {
208+ sprintf_s (_xmlStringBuffer, " %04X" , value);
209+ }
210+
211+ void TreeImportExport::ConvertDwordPtrToString (const DWORD_PTR value)
212+ {
213+ sprintf_s (_xmlStringBuffer, PRINTF_DWORD_PTR_FULL_S, value);
214+ }
215+
216+ DWORD_PTR TreeImportExport::ConvertStringToDwordPtr (const char * pValue)
217+ {
218+ DWORD_PTR result = 0 ;
219+
220+ if (pValue)
221+ {
222+ #ifdef _WIN64
223+ result = _strtoi64 (pValue, NULL , 16 );
224+ #else
225+ result = strtoul (pValue, NULL , 16 );
226+ #endif
227+ }
228+
229+ return result;
230+ }
231+
232+ WORD TreeImportExport::ConvertStringToWord (const char * pValue)
233+ {
234+ WORD result = 0 ;
235+
236+ if (pValue)
237+ {
238+ result = (WORD)strtoul (pValue, NULL , 16 );
239+ }
240+
241+ return result;
242+ }
243+
244+ bool TreeImportExport::ConvertStringToBool (const char * pValue)
245+ {
246+ if (pValue)
247+ {
248+ if (pValue[0 ] == ' 1' )
249+ {
250+ return true ;
251+ }
252+ }
253+
254+ return false ;
255+ }
0 commit comments