Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 2e7eef2

Browse files
committedAug 5, 2014
First release
0 parents  commit 2e7eef2

27 files changed

+2875
-0
lines changed
 

‎ASByteArray.cpp

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
Copyright 2014 F-Secure
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#include "ASByteArray.h"
18+
#include "FlashPlayerConfigBuilder.h"
19+
#include "Logger.h"
20+
21+
ASByteArray::ASByteArray(void)
22+
{
23+
}
24+
25+
26+
ASByteArray::ASByteArray(UINT32* ptr)
27+
{
28+
m_addr = (UINT32*)((UINT32)ptr & 0xfffffff8);
29+
m_config = FlashPlayerConfigBuilder::instance().getConfig();
30+
}
31+
32+
33+
ASByteArray* ASByteArray::create(UINT32* ptr)
34+
{
35+
if (!ASByteArray::isByteArray(ptr))
36+
{
37+
return NULL;
38+
}
39+
40+
return new ASByteArray(ptr);
41+
}
42+
43+
44+
bool ASByteArray::isByteArray(UINT32* ptr)
45+
{
46+
// Untag the pointer and try to read it
47+
UINT32* addr = (UINT32*)((UINT32)ptr & 0xfffffff8);
48+
Config* config = FlashPlayerConfigBuilder::instance().getConfig();
49+
50+
if (!WINDOWS::IsBadReadPtr((const void*)addr, 16))
51+
{
52+
UINT32* ba = (UINT32*)addr;
53+
ADDRINT vtableAddr = (UINT32)ba[0];
54+
if (vtableAddr == (config->loadOffset + config->byteArrayVTableRVA))
55+
{
56+
return true;
57+
}
58+
}
59+
60+
return false;
61+
}
62+
63+
64+
UINT8* ASByteArray::getData()
65+
{
66+
UINT32* buffer = (UINT32*)m_addr[m_config->bufferOffsetInByteArray/sizeof(UINT32)];
67+
UINT8* data = (UINT8*)buffer[m_config->dataOffsetInByteArrayBuffer/sizeof(UINT32)];
68+
UINT32 count = buffer[m_config->countOffsetInByteArrayBuffer/sizeof(UINT32)];
69+
70+
UINT8* copyOfData = (UINT8*)malloc(count);
71+
if (copyOfData == NULL)
72+
{
73+
return NULL;
74+
}
75+
76+
memcpy(copyOfData, data, count);
77+
return copyOfData;
78+
}
79+
80+
81+
UINT32 ASByteArray::getDataLength()
82+
{
83+
UINT32* buffer = (UINT32*)m_addr[m_config->bufferOffsetInByteArray/sizeof(UINT32)];
84+
UINT32 count = buffer[m_config->countOffsetInByteArrayBuffer/sizeof(UINT32)];
85+
return count;
86+
}

‎ASByteArray.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
Copyright 2014 F-Secure
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#pragma once
18+
19+
#include "pin.H"
20+
21+
#include "FlashPlayerConfigBuilder.h"
22+
23+
class ASByteArray
24+
{
25+
public:
26+
static ASByteArray* create(UINT32* ptr);
27+
UINT8* getData();
28+
UINT32 getDataLength();
29+
30+
private:
31+
ASByteArray(void);
32+
ASByteArray(UINT32*);
33+
ASByteArray(ASByteArray const&);
34+
void operator=(ASByteArray const&);
35+
36+
static bool ASByteArray::isByteArray(UINT32*);
37+
38+
Config* m_config;
39+
UINT32* m_addr;
40+
};
41+

‎ASMethodInfo.cpp

Lines changed: 328 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,328 @@
1+
/*
2+
Copyright 2014 F-Secure
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#include "ASMethodInfo.h"
18+
#include "ASMultiname.h"
19+
#include "Logger.h"
20+
21+
map<UINT32*,ASMethodInfo*> ASMethodInfo::m_methodInfoCache;
22+
23+
static UINT32 readU30(const char *&p)
24+
{
25+
unsigned int result = p[0];
26+
if (!(result & 0x00000080))
27+
{
28+
p++;
29+
return result;
30+
}
31+
result = (result & 0x0000007f) | p[1]<<7;
32+
if (!(result & 0x00004000))
33+
{
34+
p += 2;
35+
return result;
36+
}
37+
result = (result & 0x00003fff) | p[2]<<14;
38+
if (!(result & 0x00200000))
39+
{
40+
p += 3;
41+
return result;
42+
}
43+
result = (result & 0x001fffff) | p[3]<<21;
44+
if (!(result & 0x10000000))
45+
{
46+
p += 4;
47+
return result;
48+
}
49+
result = (result & 0x0fffffff) | p[4]<<28;
50+
p += 5;
51+
return result;
52+
}
53+
54+
55+
ASMethodInfo::ASMethodInfo(void)
56+
{
57+
}
58+
59+
60+
ASMethodInfo::ASMethodInfo(UINT32* ptr) :
61+
m_methodSignatureBuilt(false)
62+
{
63+
m_methodInfo = ptr;
64+
m_config = FlashPlayerConfigBuilder::instance().getConfig();
65+
}
66+
67+
68+
ASMethodInfo* ASMethodInfo::create(UINT32* ptr)
69+
{
70+
if (m_methodInfoCache.find(ptr) != m_methodInfoCache.end())
71+
{
72+
return m_methodInfoCache[ptr];
73+
}
74+
else
75+
{
76+
m_methodInfoCache[ptr] = new ASMethodInfo(ptr);
77+
return m_methodInfoCache[ptr];
78+
}
79+
}
80+
81+
82+
UINT32 ASMethodInfo::getMethodId()
83+
{
84+
return m_methodInfo[m_config->methodIdOffsetInMethodInfo>>2];
85+
}
86+
87+
88+
void ASMethodInfo::buildMethodSignature()
89+
{
90+
UINT32* pool = (UINT32*)m_methodInfo[m_config->poolOffsetInMethodInfo>>2];
91+
UINT32 method_id = m_methodInfo[m_config->methodIdOffsetInMethodInfo>>2];
92+
UINT32 flags = m_methodInfo[m_config->flagsOffsetInMethodInfo>>2];
93+
UINT32* abc_info_pos = (UINT32*)m_methodInfo[m_config->abcInfoPosOffsetInMethodInfo>>2];
94+
UINT32* precompNames = (UINT32*)pool[m_config->precompNamesOffsetInPoolObject/4];
95+
96+
precompNames = precompNames + m_config->precompNamesHeaderSize/sizeof(UINT32);
97+
98+
// Do some manual ABC parsing to find parameter and return value information
99+
const char* pos = (char*)abc_info_pos;
100+
101+
UINT32 param_count = readU30(pos);
102+
103+
UINT32 ret_type_name_index = readU30(pos);
104+
if (ret_type_name_index != 0)
105+
{
106+
UINT32* name = (UINT32*)&precompNames[ret_type_name_index*(m_config->multinameSize/sizeof(UINT32))];
107+
ASMultiname* mn = ASMultiname::create(name);
108+
109+
if (mn == NULL)
110+
{
111+
m_returnValueType = "null";
112+
}
113+
else
114+
{
115+
m_returnValueType = mn->getFormatted();
116+
}
117+
}
118+
else
119+
{
120+
m_returnValueType = "null";
121+
}
122+
123+
for (UINT32 i=0; i < param_count; i++)
124+
{
125+
UINT32 param_name_index = readU30(pos);
126+
if (param_name_index == 0)
127+
{
128+
m_parameterTypes.push_back("null");
129+
}
130+
else
131+
{
132+
ASMultiname* mn = ASMultiname::create((UINT32*)&precompNames[param_name_index*(m_config->multinameSize/sizeof(UINT32))]);
133+
if (mn == NULL)
134+
{
135+
m_parameterTypes.push_back("null");
136+
}
137+
else
138+
{
139+
m_parameterTypes.push_back(mn->getFormatted());
140+
}
141+
}
142+
}
143+
}
144+
145+
146+
string ASMethodInfo::getName()
147+
{
148+
UINT32* declaringScopeOrTraits = (UINT32*)m_methodInfo[m_config->traitsOffsetInMethodInfo>>2];
149+
UINT32* pool = (UINT32*)m_methodInfo[m_config->poolOffsetInMethodInfo>>2];
150+
UINT32 method_id = m_methodInfo[m_config->methodIdOffsetInMethodInfo>>2];
151+
UINT32 flags = m_methodInfo[m_config->flagsOffsetInMethodInfo>>2];
152+
UINT32* precompNames = (UINT32*)pool[m_config->precompNamesOffsetInPoolObject/4];
153+
154+
/**
155+
* Getting the name is easier with debug build because it has method_name_indices array that
156+
* maps method_id to an index in precompNames (precomputer multinames). With non-debug builds
157+
* we need to manually calculate that index. Since the calculation is slow, we cache the results.
158+
*/
159+
160+
INT32 methodNameIndex;
161+
162+
// Debug build is easier to handle
163+
if (m_config->debugBuild)
164+
{
165+
UINT32* method_name_indices = (UINT32*)pool[m_config->methodNameIndicesOffsetInPoolObject/4];
166+
167+
UINT32 method_name_indices_size = method_name_indices[0];
168+
if (method_id >= method_name_indices_size)
169+
{
170+
LOGF("ERROR: method_id %d is larger than method_name_indices_size %d\n", method_id, method_name_indices_size);
171+
return "ERROR";
172+
}
173+
174+
// The first two element are for other stuff
175+
methodNameIndex = method_name_indices[method_id+2];
176+
177+
if (methodNameIndex == 0)
178+
{
179+
LOGF("ERROR: methodNameIndex is zero for method_id 0x%x\n", method_id);
180+
return "ERROR";
181+
}
182+
else if (methodNameIndex > 0)
183+
{
184+
// No name needed
185+
return "";
186+
}
187+
188+
// Change the sign because we prefer positive indeces
189+
methodNameIndex = -methodNameIndex;
190+
}
191+
else
192+
{
193+
UINT32* traitsPtr = getTraitsPtr();
194+
ASTraits* as_traits = ASTraits::create(traitsPtr);
195+
methodNameIndex = as_traits->methodIdToMethodNameIndex(method_id);
196+
if (methodNameIndex == -1)
197+
{
198+
// No name needed
199+
return "";
200+
}
201+
}
202+
203+
UINT32* pMultiname = precompNames + m_config->precompNamesHeaderSize/sizeof(UINT32);
204+
pMultiname += methodNameIndex*(m_config->multinameSize/sizeof(UINT32));
205+
ASMultiname* mn = ASMultiname::create(pMultiname);
206+
if (mn == NULL)
207+
{
208+
LOGF("ERROR: Creating ASMultiname from precompNames failed\n");
209+
return "ERROR";
210+
}
211+
return mn->getFormatted();
212+
}
213+
214+
215+
UINT32 ASMethodInfo::getFlags()
216+
{
217+
return m_methodInfo[m_config->flagsOffsetInMethodInfo>>2];
218+
}
219+
220+
221+
UINT32* ASMethodInfo::getTraitsPtr()
222+
{
223+
224+
UINT32* declaringScopeOrTraits = (UINT32*)m_methodInfo[m_config->traitsOffsetInMethodInfo/4];
225+
226+
if ((UINT32)declaringScopeOrTraits & 1)
227+
{
228+
declaringScopeOrTraits = (UINT32*)((UINT32)declaringScopeOrTraits & ~1);
229+
return (UINT32*)declaringScopeOrTraits[2];
230+
}
231+
else
232+
{
233+
return declaringScopeOrTraits;
234+
}
235+
}
236+
237+
238+
string ASMethodInfo::getMethodNameWithTraits()
239+
{
240+
if (!m_methodNameWithTraits.empty())
241+
{
242+
return m_methodNameWithTraits;
243+
}
244+
245+
UINT32* pTraits = getTraitsPtr();
246+
if (((UINT32)pTraits & ~3) == NULL)
247+
{
248+
return "Function/<anonymous>";
249+
}
250+
251+
ASTraits* traits = ASTraits::create(pTraits);
252+
253+
if (traits == NULL)
254+
{
255+
LOGF("ERROR: ASTraits::create returned NULL\n");
256+
m_methodNameWithTraits = "ERROR";
257+
return m_methodNameWithTraits;
258+
}
259+
260+
UINT32* init = traits->getInit();
261+
if (init == NULL)
262+
{
263+
LOGF("ERROR: traits->getInit returned NULL\n");
264+
m_methodNameWithTraits = "ERROR";
265+
return m_methodNameWithTraits;
266+
}
267+
268+
string traitsName = traits->getName();
269+
string name = getName();
270+
271+
if (init == m_methodInfo)
272+
{
273+
UINT8 posType = traits->getPosType();
274+
275+
if (posType == TRAITSTYPE_SCRIPT)
276+
{
277+
m_methodNameWithTraits = traitsName + "$init";
278+
return m_methodNameWithTraits;
279+
}
280+
else if (posType == TRAITSTYPE_CLASS)
281+
{
282+
m_methodNameWithTraits = traitsName + "cinit";
283+
return m_methodNameWithTraits;
284+
}
285+
else
286+
{
287+
m_methodNameWithTraits = traitsName;
288+
return m_methodNameWithTraits;
289+
}
290+
}
291+
292+
UINT32 flags = getFlags();
293+
string sep = "/";
294+
295+
if (flags & IS_GETTER)
296+
{
297+
sep = "/get ";
298+
}
299+
else if (flags & IS_SETTER)
300+
{
301+
sep = "/set ";
302+
}
303+
304+
m_methodNameWithTraits = traitsName + sep + name;
305+
return m_methodNameWithTraits;
306+
}
307+
308+
309+
string ASMethodInfo::getReturnValueType()
310+
{
311+
if (!m_methodSignatureBuilt)
312+
{
313+
buildMethodSignature();
314+
}
315+
316+
return m_returnValueType;
317+
}
318+
319+
320+
const vector<string>* ASMethodInfo::getParameterTypes()
321+
{
322+
if (!m_methodSignatureBuilt)
323+
{
324+
buildMethodSignature();
325+
}
326+
327+
return &m_parameterTypes;
328+
}

‎ASMethodInfo.h

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
Copyright 2014 F-Secure
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#pragma once
18+
19+
#include "pin.H"
20+
21+
#include "FlashPlayerConfigBuilder.h"
22+
#include "ASString.h"
23+
#include "ASTraits.h"
24+
25+
class ASMethodInfo
26+
{
27+
public:
28+
static ASMethodInfo* create(UINT32* ptr);
29+
string getName();
30+
UINT32* getTraitsPtr();
31+
string getMethodNameWithTraits();
32+
UINT32 getFlags();
33+
UINT32 getMethodId();
34+
35+
string getReturnValueType();
36+
const vector<string>* getParameterTypes();
37+
38+
private:
39+
ASMethodInfo(void);
40+
ASMethodInfo(UINT32*);
41+
ASMethodInfo(ASMethodInfo const&);
42+
void operator=(ASMethodInfo const&);
43+
44+
void buildMethodSignature();
45+
46+
Config* m_config;
47+
UINT32* m_methodInfo;
48+
49+
string m_methodNameWithTraits;
50+
51+
bool m_methodSignatureBuilt;
52+
string m_returnValueType;
53+
vector<string> m_parameterTypes;
54+
55+
map<UINT32,UINT32> methodIdToMethodNameIndex;
56+
57+
static map<UINT32*,ASMethodInfo*> m_methodInfoCache;
58+
59+
static const UINT32 IS_GETTER = 0x100;
60+
static const UINT32 IS_SETTER = 0x200;
61+
};
62+

‎ASMultiname.cpp

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
Copyright 2014 F-Secure
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#include "ASMultiname.h"
18+
#include "ASString.h"
19+
#include "FlashPlayerConfigBuilder.h"
20+
#include "Logger.h"
21+
22+
map<UINT32*,ASMultiname*> ASMultiname::m_multinameCache;
23+
24+
ASMultiname::ASMultiname(UINT32* ptr)
25+
{
26+
m_config = FlashPlayerConfigBuilder::instance().getConfig();
27+
m_addr = ptr;
28+
}
29+
30+
31+
ASMultiname* ASMultiname::create(UINT32* ptr)
32+
{
33+
if (m_multinameCache.find(ptr) == m_multinameCache.end())
34+
{
35+
m_multinameCache[ptr] = new ASMultiname(ptr);
36+
}
37+
38+
return m_multinameCache[ptr];
39+
}
40+
41+
42+
string ASMultiname::format(UINT32* ns, UINT32* name, bool hideNonPublicNamespaces)
43+
{
44+
Config* config = FlashPlayerConfigBuilder::instance().getConfig();
45+
46+
UINT32* p_uri = (UINT32*)ns[config->uriOffsetInNamespace/4];
47+
48+
ASString* as_str = ASString::create(name);
49+
string str_name = as_str->getString();
50+
51+
// Lower 3 bytes zero (public) and String length == 0, or
52+
// non-public and we want to hide
53+
if (((((UINT32)p_uri & 7) == 0) && p_uri[4] == 0) || (hideNonPublicNamespaces && (((UINT32)p_uri & 7) != 0)))
54+
{
55+
return str_name;
56+
}
57+
else
58+
{
59+
p_uri = (UINT32*)((UINT32)p_uri & 0xfffffff8);
60+
61+
as_str = ASString::create(p_uri);
62+
string str_ns = as_str->getString();
63+
64+
return str_ns + "::" + str_name;
65+
}
66+
}
67+
68+
UINT32* ASMultiname::getNamePtr()
69+
{
70+
UINT32* p_name = (UINT32*)m_addr[0];
71+
return p_name;
72+
}
73+
74+
UINT32* ASMultiname::getNamespacePtr()
75+
{
76+
UINT32 multiname_flags = m_addr[2];
77+
UINT32* pNamespaceOrNamespaceSet = (UINT32*)m_addr[1];
78+
UINT32* pNamespace = pNamespaceOrNamespaceSet;
79+
80+
// Namespace set?
81+
if ((multiname_flags & NSSET) == NSSET)
82+
{
83+
pNamespace = (UINT32*)pNamespaceOrNamespaceSet[m_config->namespacesOffsetInNamespaceSet/sizeof(UINT32)];
84+
}
85+
86+
return pNamespace;
87+
}
88+
89+
90+
string ASMultiname::getFormatted()
91+
{
92+
return ASMultiname::format(getNamespacePtr(), getNamePtr());
93+
}

‎ASMultiname.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
Copyright 2014 F-Secure
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#pragma once
18+
19+
#include "pin.H"
20+
21+
#include "FlashPlayerConfigBuilder.h"
22+
23+
class ASMultiname
24+
{
25+
public:
26+
27+
static ASMultiname* create(UINT32* ptr);
28+
static string format(UINT32* ns, UINT32* name, bool hideNonPublicNamespaces=true);
29+
string getFormatted();
30+
31+
private:
32+
33+
ASMultiname(void);
34+
ASMultiname(UINT32*);
35+
ASMultiname(ASMultiname const&);
36+
void operator=(ASMultiname const&);
37+
38+
UINT32* getNamespacePtr();
39+
UINT32* getNamePtr();
40+
41+
Config* m_config;
42+
UINT32* m_addr;
43+
44+
static map<UINT32*,ASMultiname*> m_multinameCache;
45+
46+
const static UINT32 NSSET = 0x10;
47+
};
48+

‎ASString.cpp

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
Copyright 2014 F-Secure
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#include "ASString.h"
18+
#include "Logger.h"
19+
20+
ASString::ASString(void)
21+
{
22+
23+
}
24+
25+
ASString::ASString(UINT32* ptr)
26+
{
27+
m_tagged = ((UINT32)ptr & 0x7) != 0;
28+
m_addr = (UINT32*)((UINT32)ptr & 0xfffffff8);
29+
m_config = FlashPlayerConfigBuilder::instance().getConfig();
30+
}
31+
32+
33+
ASString* ASString::create(UINT32* ptr)
34+
{
35+
if (!ASString::isString(ptr))
36+
{
37+
return NULL;
38+
}
39+
40+
return new ASString(ptr);
41+
}
42+
43+
44+
bool ASString::isString(UINT32* addr)
45+
{
46+
// Untag the pointer and try to read it
47+
addr = (UINT32*)((UINT32)addr & 0xfffffff8);
48+
Config* config = FlashPlayerConfigBuilder::instance().getConfig();
49+
50+
if (!WINDOWS::IsBadReadPtr((const void*)addr, 16))
51+
{
52+
UINT32* obj = (UINT32*)addr;
53+
ADDRINT vtableAddr = (UINT32)obj[0];
54+
if (vtableAddr == (config->loadOffset + config->stringVTableRVA))
55+
{
56+
return true;
57+
}
58+
}
59+
60+
return false;
61+
}
62+
63+
64+
UINT8* ASString::getPtrToBuf()
65+
{
66+
return (UINT8*)m_addr[m_config->stringBufferOffset>>2];
67+
}
68+
69+
string ASString::getString(bool verbose)
70+
{
71+
if (!WINDOWS::IsBadReadPtr((const void*)((ADDRINT)m_addr + m_config->stringLengthOffset), 16) && !WINDOWS::IsBadReadPtr((const void*)((ADDRINT)m_addr + m_config->stringBufferOffset), 16))
72+
{
73+
UINT32 flags = m_addr[0x14>>2];
74+
UINT8* buffer = NULL;
75+
76+
// Dependent string?
77+
if (flags & 4)
78+
{
79+
80+
ASString* master = ASString::create((UINT32*)m_addr[0xc>>2]);
81+
buffer = master->getPtrToBuf();
82+
// Offset
83+
buffer += m_addr[m_config->stringBufferOffset>>2];
84+
}
85+
else
86+
{
87+
buffer = (UINT8*)m_addr[m_config->stringBufferOffset>>2];
88+
}
89+
90+
UINT32 length = m_addr[m_config->stringLengthOffset>>2];
91+
92+
93+
if (!WINDOWS::IsBadReadPtr((const void*)buffer, length))
94+
{
95+
string s = string((const char*)buffer, length);
96+
return s;
97+
}
98+
}
99+
100+
return NULL;
101+
}

‎ASString.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
Copyright 2014 F-Secure
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#pragma once
18+
19+
#include "pin.H"
20+
21+
#include "FlashPlayerConfigBuilder.h"
22+
23+
class ASString
24+
{
25+
public:
26+
27+
enum Type
28+
{
29+
DYNAMIC_STRING = 0,
30+
STATIC_STRING = 1,
31+
DEPENDENT_STRING = 2
32+
};
33+
34+
static ASString* create(UINT32* ptr);
35+
string getString(bool verbose=false);
36+
37+
private:
38+
ASString(void);
39+
ASString(UINT32*);
40+
ASString(ASString const&);
41+
void operator=(ASString const&);
42+
43+
static BOOL isString(UINT32* addr);
44+
UINT8* getPtrToBuf();
45+
46+
bool m_tagged;
47+
UINT32* m_addr;
48+
Config* m_config;
49+
};
50+

‎ASTraits.cpp

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
/*
2+
Copyright 2014 F-Secure
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#include "ASTraits.h"
18+
#include "ASMultiname.h"
19+
#include "Logger.h"
20+
21+
map<UINT32*,ASTraits*> ASTraits::m_traitsCache;
22+
23+
static UINT32 readU30(const char *&p)
24+
{
25+
unsigned int result = p[0];
26+
if (!(result & 0x00000080))
27+
{
28+
p++;
29+
return result;
30+
}
31+
result = (result & 0x0000007f) | p[1]<<7;
32+
if (!(result & 0x00004000))
33+
{
34+
p += 2;
35+
return result;
36+
}
37+
result = (result & 0x00003fff) | p[2]<<14;
38+
if (!(result & 0x00200000))
39+
{
40+
p += 3;
41+
return result;
42+
}
43+
result = (result & 0x001fffff) | p[3]<<21;
44+
if (!(result & 0x10000000))
45+
{
46+
p += 4;
47+
return result;
48+
}
49+
result = (result & 0x0fffffff) | p[4]<<28;
50+
p += 5;
51+
return result;
52+
}
53+
54+
55+
ASTraits::ASTraits(void)
56+
{
57+
}
58+
59+
ASTraits::ASTraits(UINT32* ptr) :
60+
m_methodIdToMethodNameIndexPopulated(false)
61+
{
62+
m_traits = ptr;
63+
m_config = FlashPlayerConfigBuilder::instance().getConfig();
64+
}
65+
66+
67+
ASTraits* ASTraits::create(UINT32* ptr)
68+
{
69+
if (m_traitsCache.find(ptr) != m_traitsCache.end())
70+
{
71+
return m_traitsCache[ptr];
72+
}
73+
else
74+
{
75+
m_traitsCache[ptr] = new ASTraits(ptr);
76+
return m_traitsCache[ptr];
77+
}
78+
}
79+
80+
81+
// Construct the name using info in private fields
82+
string ASTraits::getName()
83+
{
84+
if (!m_name.empty())
85+
{
86+
return m_name;
87+
}
88+
89+
UINT32* p_ns = (UINT32*)m_traits[m_config->namespaceOffsetInTraits/4];
90+
UINT32* p_name = (UINT32*)m_traits[m_config->nameOffsetInTraits/4];
91+
92+
if (p_ns == NULL)
93+
{
94+
LOGF("ERROR: namespace pointer is NULL in Traits object\n");
95+
return "ERROR";
96+
}
97+
98+
if (p_name == NULL)
99+
{
100+
LOGF("ERROR: name pointer is NULL in Traits object\n");
101+
return "ERROR";
102+
}
103+
104+
m_name = ASMultiname::format(p_ns, p_name, false);
105+
return m_name;
106+
}
107+
108+
109+
UINT32* ASTraits::getInit()
110+
{
111+
return (UINT32*)m_traits[m_config->initOffsetInTraits/4];
112+
}
113+
114+
115+
UINT8 ASTraits::getPosType()
116+
{
117+
UINT8* tmp = (UINT8*)m_traits;
118+
return tmp[m_config->posTypeOffsetInTraits];
119+
}
120+
121+
122+
UINT32 ASTraits::methodIdToMethodNameIndex(UINT32 method_id)
123+
{
124+
if (m_methodIdToMethodNameIndexPopulated)
125+
{
126+
if (m_methodIdToMethodNameIndex.find(method_id) == m_methodIdToMethodNameIndex.end())
127+
{
128+
return -1;
129+
}
130+
else
131+
{
132+
return m_methodIdToMethodNameIndex[method_id];
133+
}
134+
}
135+
136+
UINT32* traitsPtr = m_traits;
137+
UINT8 posType = getPosType();
138+
UINT32* traitsPos = (UINT32*)traitsPtr[m_config->traitsPosOffsetOffsetInTraits/4];
139+
140+
const char* pos = (char*)traitsPos;
141+
142+
if (posType == TRAITSTYPE_INSTANCE || posType == TRAITSTYPE_INTERFACE)
143+
{
144+
UINT32 qname = readU30(pos);
145+
UINT32 baseTraits = readU30(pos);
146+
147+
UINT8 flags2 = *pos++;
148+
if ((flags2 & 8) != 0)
149+
{
150+
UINT32 dummy = readU30(pos);
151+
}
152+
153+
UINT32 interfaceCount = readU30(pos);
154+
for (UINT32 i=0; i < interfaceCount; i++)
155+
{
156+
UINT32 dummy = readU30(pos);
157+
}
158+
}
159+
160+
if (posType == TRAITSTYPE_INSTANCE || posType == TRAITSTYPE_INTERFACE || posType == TRAITSTYPE_CLASS || posType == TRAITSTYPE_SCRIPT)
161+
{
162+
UINT32 init_index = readU30(pos);
163+
}
164+
165+
// AbcParser::parseTraits
166+
UINT32 count = readU30(pos);
167+
for (UINT32 i=0; i < count; i++)
168+
{
169+
UINT32 qindex = readU30(pos);
170+
UINT8 tag = *pos++;
171+
UINT8 kind = tag & 0xf;
172+
UINT32 method_index = NULL;
173+
UINT32 earlyDispId = 0;
174+
UINT32 slot_id = 0;
175+
UINT32 typeName = 0;
176+
177+
switch (kind)
178+
{
179+
case 1:
180+
case 2:
181+
case 3:
182+
earlyDispId = readU30(pos);
183+
method_index = readU30(pos);
184+
break;
185+
case 4:
186+
slot_id = readU30(pos);
187+
method_index = readU30(pos);
188+
break;
189+
case 0:
190+
case 6:
191+
slot_id = readU30(pos);
192+
typeName = readU30(pos);
193+
// This is called value_index in original source code
194+
method_index = readU30(pos);
195+
if (method_index)
196+
{
197+
pos += 1;
198+
}
199+
break;
200+
default:
201+
break;
202+
}
203+
204+
// Metadata?
205+
if (tag & 0x40)
206+
{
207+
UINT32 metadataCount = readU30(pos);
208+
for (UINT32 metadata = 0; metadata < metadataCount; ++metadata)
209+
{
210+
const UINT32 index = readU30(pos);
211+
}
212+
}
213+
214+
m_methodIdToMethodNameIndex[method_index] = qindex;
215+
}
216+
217+
m_methodIdToMethodNameIndexPopulated = true;
218+
if (m_methodIdToMethodNameIndex.find(method_id) == m_methodIdToMethodNameIndex.end())
219+
{
220+
return -1;
221+
}
222+
else
223+
{
224+
return m_methodIdToMethodNameIndex[method_id];
225+
}
226+
}

‎ASTraits.h

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
Copyright 2014 F-Secure
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#pragma once
18+
19+
#include "pin.H"
20+
21+
#include "FlashPlayerConfigBuilder.h"
22+
#include "ASString.h"
23+
24+
enum TraitsPosType
25+
{
26+
TRAITSTYPE_INSTANCE = 0,
27+
TRAITSTYPE_CLASS = 1,
28+
TRAITSTYPE_SCRIPT = 2,
29+
TRAITSTYPE_CATCH = 3,
30+
TRAITSTYPE_ACTIVATION = 4,
31+
TRAITSTYPE_NVA = 5,
32+
TRAITSTYPE_RT = 6,
33+
TRAITSTYPE_INTERFACE = 7
34+
};
35+
36+
class ASTraits
37+
{
38+
public:
39+
static ASTraits* create(UINT32* ptr);
40+
41+
UINT32 methodIdToMethodNameIndex(UINT32 method_id);
42+
43+
string getName();
44+
UINT32* getInit();
45+
UINT8 getPosType();
46+
47+
private:
48+
ASTraits(void);
49+
ASTraits(UINT32*);
50+
ASTraits(ASTraits const&);
51+
void operator=(ASTraits const&);
52+
53+
Config* m_config;
54+
UINT32* m_traits;
55+
string m_name;
56+
bool m_methodIdToMethodNameIndexPopulated;
57+
map <UINT32,UINT32> m_methodIdToMethodNameIndex;
58+
59+
static map<UINT32*,ASTraits*> m_traitsCache;
60+
};
61+

‎FlashPlayerConfigBuilder.cpp

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
/*
2+
Copyright 2014 F-Secure
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#include "FlashPlayerConfigBuilder.h"
18+
19+
FlashPlayerConfigBuilder::FlashPlayerConfigBuilder(void)
20+
{
21+
m_supportedConfigs["10.3.181.23_win_sa_debug"].versionStr = "WIN 10,3,181,22";
22+
m_supportedConfigs["10.3.181.23_win_sa_debug"].versionStrRVA = 0x453f74;
23+
m_supportedConfigs["10.3.181.23_win_sa_debug"].setInterpRVA = 0x3F2A46;
24+
m_supportedConfigs["10.3.181.23_win_sa_debug"].verifyOnCallRVA = 0x3F3131;
25+
m_supportedConfigs["10.3.181.23_win_sa_debug"].byteArrayVTableRVA = 0x55d698;
26+
m_supportedConfigs["10.3.181.23_win_sa_debug"].bufferOffsetInByteArray = 0x10;
27+
m_supportedConfigs["10.3.181.23_win_sa_debug"].dataOffsetInByteArrayBuffer = 0x24;
28+
m_supportedConfigs["10.3.181.23_win_sa_debug"].countOffsetInByteArrayBuffer = 0x2c;
29+
m_supportedConfigs["10.3.181.23_win_sa_debug"].stringVTableRVA = 0x55d4f8;
30+
m_supportedConfigs["10.3.181.23_win_sa_debug"].stringLengthOffset = 0x10;
31+
m_supportedConfigs["10.3.181.23_win_sa_debug"].stringBufferOffset = 0x8;
32+
m_supportedConfigs["10.3.181.23_win_sa_debug"].methodInfoOffsetInMethodEnv = 0x4;
33+
m_supportedConfigs["10.3.181.23_win_sa_debug"].invokerOffsetInMethodInfo = 0x4;
34+
m_supportedConfigs["10.3.181.23_win_sa_debug"].traitsOffsetInMethodInfo = 0xc;
35+
m_supportedConfigs["10.3.181.23_win_sa_debug"].poolOffsetInMethodInfo = 0x14;
36+
m_supportedConfigs["10.3.181.23_win_sa_debug"].abcInfoPosOffsetInMethodInfo = 0x18;
37+
m_supportedConfigs["10.3.181.23_win_sa_debug"].methodIdOffsetInMethodInfo = 0x1c;
38+
m_supportedConfigs["10.3.181.23_win_sa_debug"].flagsOffsetInMethodInfo = 0x34;
39+
m_supportedConfigs["10.3.181.23_win_sa_debug"].initOffsetInTraits = 0x48;
40+
m_supportedConfigs["10.3.181.23_win_sa_debug"].traitsPosOffsetOffsetInTraits = 0x50;
41+
m_supportedConfigs["10.3.181.23_win_sa_debug"].posTypeOffsetInTraits = 0x79;
42+
m_supportedConfigs["10.3.181.23_win_sa_debug"].namespaceOffsetInTraits = 0x3c;
43+
m_supportedConfigs["10.3.181.23_win_sa_debug"].nameOffsetInTraits = 0x40;
44+
m_supportedConfigs["10.3.181.23_win_sa_debug"].methodsOffsetInPoolObject = 0x8c;
45+
m_supportedConfigs["10.3.181.23_win_sa_debug"].methodNameIndicesOffsetInPoolObject = 0x90;
46+
m_supportedConfigs["10.3.181.23_win_sa_debug"].precompNamesOffsetInPoolObject = 0x50;
47+
m_supportedConfigs["10.3.181.23_win_sa_debug"].uriOffsetInNamespace = 0x10;
48+
m_supportedConfigs["10.3.181.23_win_sa_debug"].namespacesOffsetInNamespaceSet = 0x4;
49+
m_supportedConfigs["10.3.181.23_win_sa_debug"].multinameSize = 0x10;
50+
m_supportedConfigs["10.3.181.23_win_sa_debug"].precompNamesHeaderSize = 0x8;
51+
m_supportedConfigs["10.3.181.23_win_sa_debug"].debugBuild = true;
52+
53+
m_supportedConfigs["10.3.181.23_win_sa"].versionStr = "WIN 10,3,181,22";
54+
m_supportedConfigs["10.3.181.23_win_sa"].versionStrRVA = 0x42a528;
55+
m_supportedConfigs["10.3.181.23_win_sa"].setInterpRVA = 0x3D3646;
56+
m_supportedConfigs["10.3.181.23_win_sa"].verifyOnCallRVA = 0x3d3c8a;
57+
m_supportedConfigs["10.3.181.23_win_sa"].byteArrayVTableRVA = 0x4D73B0;
58+
m_supportedConfigs["10.3.181.23_win_sa"].bufferOffsetInByteArray = 0x10;
59+
m_supportedConfigs["10.3.181.23_win_sa"].dataOffsetInByteArrayBuffer = 0x24;
60+
m_supportedConfigs["10.3.181.23_win_sa"].countOffsetInByteArrayBuffer = 0x2c;
61+
m_supportedConfigs["10.3.181.23_win_sa"].stringVTableRVA = 0x4d72d0;
62+
m_supportedConfigs["10.3.181.23_win_sa"].stringLengthOffset = 0x10;
63+
m_supportedConfigs["10.3.181.23_win_sa"].stringBufferOffset = 0x8;
64+
m_supportedConfigs["10.3.181.23_win_sa"].methodInfoOffsetInMethodEnv = 0x4;
65+
m_supportedConfigs["10.3.181.23_win_sa"].invokerOffsetInMethodInfo = 0x4;
66+
m_supportedConfigs["10.3.181.23_win_sa"].traitsOffsetInMethodInfo = 0xc;
67+
m_supportedConfigs["10.3.181.23_win_sa"].poolOffsetInMethodInfo = 0x14;
68+
m_supportedConfigs["10.3.181.23_win_sa"].abcInfoPosOffsetInMethodInfo = 0x18;
69+
m_supportedConfigs["10.3.181.23_win_sa"].methodIdOffsetInMethodInfo = 0x1c;
70+
m_supportedConfigs["10.3.181.23_win_sa"].flagsOffsetInMethodInfo = 0x30;
71+
m_supportedConfigs["10.3.181.23_win_sa"].initOffsetInTraits = 0x48;
72+
m_supportedConfigs["10.3.181.23_win_sa"].traitsPosOffsetOffsetInTraits = 0x50;
73+
m_supportedConfigs["10.3.181.23_win_sa"].posTypeOffsetInTraits = 0x79;
74+
m_supportedConfigs["10.3.181.23_win_sa"].namespaceOffsetInTraits = 0x3c;
75+
m_supportedConfigs["10.3.181.23_win_sa"].nameOffsetInTraits = 0x40;
76+
m_supportedConfigs["10.3.181.23_win_sa"].methodsOffsetInPoolObject = 0x88;
77+
m_supportedConfigs["10.3.181.23_win_sa"].methodNameIndicesOffsetInPoolObject = NULL;
78+
m_supportedConfigs["10.3.181.23_win_sa"].precompNamesOffsetInPoolObject = 0x50;
79+
m_supportedConfigs["10.3.181.23_win_sa"].uriOffsetInNamespace = 0x10;
80+
m_supportedConfigs["10.3.181.23_win_sa"].namespacesOffsetInNamespaceSet = 0x4;
81+
m_supportedConfigs["10.3.181.23_win_sa"].multinameSize = 0x10;
82+
m_supportedConfigs["10.3.181.23_win_sa"].precompNamesHeaderSize = 0x8;
83+
m_supportedConfigs["10.3.181.23_win_sa"].debugBuild = false;
84+
85+
m_supportedConfigs["10.3.181.23_winax"].versionStr = "WIN 10,3,181,23";
86+
m_supportedConfigs["10.3.181.23_winax"].versionStrRVA = 0x4CC970;
87+
m_supportedConfigs["10.3.181.23_winax"].setInterpRVA = 0x406766;
88+
m_supportedConfigs["10.3.181.23_winax"].verifyOnCallRVA = 0x406DAA;
89+
m_supportedConfigs["10.3.181.23_winax"].byteArrayVTableRVA = 0x57D038;
90+
m_supportedConfigs["10.3.181.23_winax"].bufferOffsetInByteArray = 0x10;
91+
m_supportedConfigs["10.3.181.23_winax"].dataOffsetInByteArrayBuffer = 0x24;
92+
m_supportedConfigs["10.3.181.23_winax"].countOffsetInByteArrayBuffer = 0x2c;
93+
m_supportedConfigs["10.3.181.23_winax"].stringVTableRVA = 0x57CF60;
94+
m_supportedConfigs["10.3.181.23_winax"].stringLengthOffset = 0x10;
95+
m_supportedConfigs["10.3.181.23_winax"].stringBufferOffset = 0x8;
96+
m_supportedConfigs["10.3.181.23_winax"].methodInfoOffsetInMethodEnv = 0x4;
97+
m_supportedConfigs["10.3.181.23_winax"].invokerOffsetInMethodInfo = 0x4;
98+
m_supportedConfigs["10.3.181.23_winax"].traitsOffsetInMethodInfo = 0xc;
99+
m_supportedConfigs["10.3.181.23_winax"].poolOffsetInMethodInfo = 0x14;
100+
m_supportedConfigs["10.3.181.23_winax"].abcInfoPosOffsetInMethodInfo = 0x18;
101+
m_supportedConfigs["10.3.181.23_winax"].methodIdOffsetInMethodInfo = 0x1c;
102+
m_supportedConfigs["10.3.181.23_winax"].flagsOffsetInMethodInfo = 0x30;
103+
m_supportedConfigs["10.3.181.23_winax"].initOffsetInTraits = 0x48;
104+
m_supportedConfigs["10.3.181.23_winax"].traitsPosOffsetOffsetInTraits = 0x50;
105+
m_supportedConfigs["10.3.181.23_winax"].posTypeOffsetInTraits = 0x79;
106+
m_supportedConfigs["10.3.181.23_winax"].namespaceOffsetInTraits = 0x3c;
107+
m_supportedConfigs["10.3.181.23_winax"].nameOffsetInTraits = 0x40;
108+
m_supportedConfigs["10.3.181.23_winax"].methodsOffsetInPoolObject = 0x88;
109+
m_supportedConfigs["10.3.181.23_winax"].methodNameIndicesOffsetInPoolObject = NULL;
110+
m_supportedConfigs["10.3.181.23_winax"].precompNamesOffsetInPoolObject = 0x50;
111+
m_supportedConfigs["10.3.181.23_winax"].uriOffsetInNamespace = 0x10;
112+
m_supportedConfigs["10.3.181.23_winax"].namespacesOffsetInNamespaceSet = 0x4;
113+
m_supportedConfigs["10.3.181.23_winax"].multinameSize = 0x10;
114+
m_supportedConfigs["10.3.181.23_winax"].precompNamesHeaderSize = 0x8;
115+
m_supportedConfigs["10.3.181.23_winax"].debugBuild = false;
116+
117+
m_supportedConfigs["11.1.102.62_win_sa"].versionStr = "WIN 11,1,102,62";
118+
m_supportedConfigs["11.1.102.62_win_sa"].versionStrRVA = 0x5E42AC;
119+
m_supportedConfigs["11.1.102.62_win_sa"].setInterpRVA = 0x48B9E7;
120+
m_supportedConfigs["11.1.102.62_win_sa"].verifyOnCallRVA = 0x48C02D;
121+
m_supportedConfigs["11.1.102.62_win_sa"].byteArrayVTableRVA = 0x6AAFF8;
122+
m_supportedConfigs["11.1.102.62_win_sa"].bufferOffsetInByteArray = 0x10;
123+
m_supportedConfigs["11.1.102.62_win_sa"].dataOffsetInByteArrayBuffer = 0x20;
124+
m_supportedConfigs["11.1.102.62_win_sa"].countOffsetInByteArrayBuffer = 0x28;
125+
m_supportedConfigs["11.1.102.62_win_sa"].stringVTableRVA = 0x6AAFBC;
126+
m_supportedConfigs["11.1.102.62_win_sa"].stringLengthOffset = 0x10;
127+
m_supportedConfigs["11.1.102.62_win_sa"].stringBufferOffset = 0x8;
128+
m_supportedConfigs["11.1.102.62_win_sa"].methodInfoOffsetInMethodEnv = 0x8;
129+
m_supportedConfigs["11.1.102.62_win_sa"].invokerOffsetInMethodInfo = 0x8;
130+
m_supportedConfigs["11.1.102.62_win_sa"].traitsOffsetInMethodInfo = 0x10;
131+
m_supportedConfigs["11.1.102.62_win_sa"].poolOffsetInMethodInfo = 0x18;
132+
m_supportedConfigs["11.1.102.62_win_sa"].abcInfoPosOffsetInMethodInfo = 0x1c;
133+
m_supportedConfigs["11.1.102.62_win_sa"].methodIdOffsetInMethodInfo = 0x20;
134+
m_supportedConfigs["11.1.102.62_win_sa"].flagsOffsetInMethodInfo = 0x34;
135+
m_supportedConfigs["11.1.102.62_win_sa"].initOffsetInTraits = 0x4c;
136+
m_supportedConfigs["11.1.102.62_win_sa"].traitsPosOffsetOffsetInTraits = 0x54;
137+
m_supportedConfigs["11.1.102.62_win_sa"].posTypeOffsetInTraits = 0x7d;
138+
m_supportedConfigs["11.1.102.62_win_sa"].namespaceOffsetInTraits = 0x40;
139+
m_supportedConfigs["11.1.102.62_win_sa"].nameOffsetInTraits = 0x44;
140+
m_supportedConfigs["11.1.102.62_win_sa"].methodsOffsetInPoolObject = 0x88;
141+
m_supportedConfigs["11.1.102.62_win_sa"].methodNameIndicesOffsetInPoolObject = NULL;
142+
m_supportedConfigs["11.1.102.62_win_sa"].precompNamesOffsetInPoolObject = 0x50;
143+
m_supportedConfigs["11.1.102.62_win_sa"].uriOffsetInNamespace = 0xc;
144+
m_supportedConfigs["11.1.102.62_win_sa"].namespacesOffsetInNamespaceSet = 0x8;
145+
m_supportedConfigs["11.1.102.62_win_sa"].multinameSize = 0x10;
146+
m_supportedConfigs["11.1.102.62_win_sa"].precompNamesHeaderSize = 0xc;
147+
m_supportedConfigs["11.1.102.62_win_sa"].debugBuild = false;
148+
149+
m_supportedConfigs["11.1.102.62_winax"].versionStr = "WIN 11,1,102,62";
150+
m_supportedConfigs["11.1.102.62_winax"].versionStrRVA = 0x68443C;
151+
m_supportedConfigs["11.1.102.62_winax"].setInterpRVA = 0x4BFD87;
152+
m_supportedConfigs["11.1.102.62_winax"].verifyOnCallRVA = 0x4C03CD;
153+
m_supportedConfigs["11.1.102.62_winax"].byteArrayVTableRVA = 0x7471E8;
154+
m_supportedConfigs["11.1.102.62_winax"].bufferOffsetInByteArray = 0x10;
155+
m_supportedConfigs["11.1.102.62_winax"].dataOffsetInByteArrayBuffer = 0x20;
156+
m_supportedConfigs["11.1.102.62_winax"].countOffsetInByteArrayBuffer = 0x28;
157+
m_supportedConfigs["11.1.102.62_winax"].stringVTableRVA = 0x74711C;
158+
m_supportedConfigs["11.1.102.62_winax"].stringLengthOffset = 0x10;
159+
m_supportedConfigs["11.1.102.62_winax"].stringBufferOffset = 0x8;
160+
m_supportedConfigs["11.1.102.62_winax"].methodInfoOffsetInMethodEnv = 0x8;
161+
m_supportedConfigs["11.1.102.62_winax"].invokerOffsetInMethodInfo = 0x8;
162+
m_supportedConfigs["11.1.102.62_winax"].traitsOffsetInMethodInfo = 0x10;
163+
m_supportedConfigs["11.1.102.62_winax"].poolOffsetInMethodInfo = 0x18;
164+
m_supportedConfigs["11.1.102.62_winax"].abcInfoPosOffsetInMethodInfo = 0x1c;
165+
m_supportedConfigs["11.1.102.62_winax"].methodIdOffsetInMethodInfo = 0x20;
166+
m_supportedConfigs["11.1.102.62_winax"].flagsOffsetInMethodInfo = 0x34;
167+
m_supportedConfigs["11.1.102.62_winax"].initOffsetInTraits = 0x4c;
168+
m_supportedConfigs["11.1.102.62_winax"].traitsPosOffsetOffsetInTraits = 0x54;
169+
m_supportedConfigs["11.1.102.62_winax"].posTypeOffsetInTraits = 0x7d;
170+
m_supportedConfigs["11.1.102.62_winax"].namespaceOffsetInTraits = 0x40;
171+
m_supportedConfigs["11.1.102.62_winax"].nameOffsetInTraits = 0x44;
172+
m_supportedConfigs["11.1.102.62_winax"].methodsOffsetInPoolObject = 0x88;
173+
m_supportedConfigs["11.1.102.62_winax"].methodNameIndicesOffsetInPoolObject = NULL;
174+
m_supportedConfigs["11.1.102.62_winax"].precompNamesOffsetInPoolObject = 0x50;
175+
m_supportedConfigs["11.1.102.62_winax"].uriOffsetInNamespace = 0xc;
176+
m_supportedConfigs["11.1.102.62_winax"].namespacesOffsetInNamespaceSet = 0x8;
177+
m_supportedConfigs["11.1.102.62_winax"].multinameSize = 0x10;
178+
m_supportedConfigs["11.1.102.62_winax"].precompNamesHeaderSize = 0xc;
179+
m_supportedConfigs["11.1.102.62_winax"].debugBuild = false;
180+
181+
m_currentConfig = NULL;
182+
}
183+
184+
bool FlashPlayerConfigBuilder::isSupportedFlashPlayer(IMG img)
185+
{
186+
UINT32 loadOffset = IMG_LoadOffset(img);
187+
UINT32 rdataRVA = 0;
188+
UINT32 rdataSize = 0;
189+
190+
// Find where the .rdata section is
191+
bool rdataFound = false;
192+
for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec))
193+
{
194+
if (SEC_Name(sec) == ".rdata")
195+
{
196+
rdataRVA = SEC_Address(sec) - loadOffset;
197+
rdataSize = SEC_Size(sec);
198+
rdataFound = true;
199+
break;
200+
}
201+
}
202+
203+
// If no .rdata, this is not Flash Player
204+
if (!rdataFound)
205+
{
206+
return false;
207+
}
208+
209+
for (map<string,Config>::iterator it = m_supportedConfigs.begin(); it != m_supportedConfigs.end(); ++it)
210+
{
211+
Config* fc = &it->second;
212+
213+
// Make sure the address is within .rdata
214+
if ((fc->versionStrRVA + fc->versionStr.length() + 1) > (rdataRVA + rdataSize) || (fc->versionStrRVA < rdataRVA))
215+
{
216+
continue;
217+
}
218+
219+
if (!WINDOWS::IsBadReadPtr((const void*)(fc->versionStrRVA+loadOffset), fc->versionStr.length()+1))
220+
{
221+
if (strcmp(fc->versionStr.c_str(), (const char*)(fc->versionStrRVA+loadOffset)) == 0)
222+
{
223+
// Set load offset and IMG values now that we know those
224+
fc->img = img;
225+
fc->loadOffset = loadOffset;
226+
fc->rdataRVA = rdataRVA;
227+
fc->rdataSize = rdataSize;
228+
m_currentConfig = fc;
229+
230+
return true;
231+
}
232+
}
233+
}
234+
235+
return false;
236+
}
237+
238+
Config* FlashPlayerConfigBuilder::getConfig(void)
239+
{
240+
return m_currentConfig;
241+
}

‎FlashPlayerConfigBuilder.h

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
Copyright 2014 F-Secure
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#pragma once
18+
19+
#include <map>
20+
21+
#include "pin.H"
22+
23+
namespace WINDOWS
24+
{
25+
#include <Windows.h>
26+
}
27+
28+
typedef struct Config {
29+
IMG img;
30+
UINT32 loadOffset;
31+
UINT32 rdataRVA;
32+
UINT32 rdataSize;
33+
34+
UINT32 setInterpRVA;
35+
UINT32 verifyOnCallRVA;
36+
37+
string versionStr;
38+
UINT32 versionStrRVA;
39+
40+
UINT32 byteArrayVTableRVA;
41+
UINT32 bufferOffsetInByteArray;
42+
UINT32 dataOffsetInByteArrayBuffer;
43+
UINT32 countOffsetInByteArrayBuffer;
44+
45+
UINT32 stringVTableRVA;
46+
UINT32 stringLengthOffset;
47+
UINT32 stringBufferOffset;
48+
49+
UINT32 methodInfoOffsetInMethodEnv;
50+
51+
UINT32 invokerOffsetInMethodInfo;
52+
UINT32 traitsOffsetInMethodInfo;
53+
UINT32 poolOffsetInMethodInfo;
54+
UINT32 abcInfoPosOffsetInMethodInfo;
55+
UINT32 methodIdOffsetInMethodInfo;
56+
UINT32 flagsOffsetInMethodInfo;
57+
58+
UINT32 methodsOffsetInPoolObject;
59+
UINT32 methodNameIndicesOffsetInPoolObject;
60+
61+
UINT32 initOffsetInTraits;
62+
UINT32 traitsPosOffsetOffsetInTraits;
63+
UINT32 posTypeOffsetInTraits;
64+
UINT32 namespaceOffsetInTraits;
65+
UINT32 nameOffsetInTraits;
66+
67+
UINT32 precompNamesOffsetInPoolObject;
68+
69+
UINT32 uriOffsetInNamespace;
70+
71+
UINT32 namespacesOffsetInNamespaceSet;
72+
73+
UINT32 multinameSize;
74+
UINT32 precompNamesHeaderSize;
75+
76+
bool debugBuild;
77+
} Config;
78+
79+
class FlashPlayerConfigBuilder
80+
{
81+
public:
82+
83+
static FlashPlayerConfigBuilder& instance()
84+
{
85+
static FlashPlayerConfigBuilder instance;
86+
return instance;
87+
}
88+
89+
bool isSupportedFlashPlayer(IMG img);
90+
Config* getConfig(void);
91+
92+
private:
93+
FlashPlayerConfigBuilder(void);
94+
FlashPlayerConfigBuilder(FlashPlayerConfigBuilder const&);
95+
void operator=(FlashPlayerConfigBuilder const&);
96+
97+
map<string,Config> m_supportedConfigs;
98+
Config* m_currentConfig;
99+
};

‎Logger.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
Copyright 2014 F-Secure
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#pragma once
18+
19+
#include <sstream>
20+
21+
#include "pin.H"
22+
23+
#define LOGF(...) Logger::LOGF(__VA_ARGS__)
24+
25+
class Logger
26+
{
27+
public:
28+
static void LOGF(char* fmt, ...)
29+
{
30+
va_list args;
31+
va_start(args, fmt);
32+
33+
int len = vsnprintf(NULL, 0, fmt, args) + 1;
34+
char* buf = (char*)malloc(len);
35+
36+
vsnprintf(buf, len-1, fmt, args);
37+
buf[len-1] = 0;
38+
39+
LOG(buf);
40+
41+
free(buf);
42+
va_end(args);
43+
} ;
44+
};
45+

‎README.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
Sulo
2+
====
3+
4+
Sulo is a dynamic instrumentation tool for Adobe Flash Player. It is built on [Pin](https://software.intel.com/en-us/articles/pin-a-dynamic-binary-instrumentation-tool).
5+
6+
Supported Flash versions
7+
------------------------
8+
9+
The following Flash Player builds are supported:
10+
11+
* 10.3.181.23 standalone debug
12+
* 10.3.181.23 standalone non-debug
13+
* 10.3.181.23 ActiveX
14+
* 11.1.102.62 standadlone non-debug
15+
* 11.1.102.62 ActiveX
16+
17+
You can add support for another Flash Player build by specifying some RVAs and offsets in `FlashPlayerConfigBuilder.cpp`.
18+
19+
Limitations
20+
-----------
21+
22+
Sulo supports ActionScript3 method calls only - AVM1 is not (yet) supported.
23+
24+
Building
25+
--------
26+
27+
The easiest way to build Sulo is to use the `sulo_vs2010.sln` solution file with Visual Studio 2010.
28+
29+
1. Download [Intel Pin kit for Visual Studio 2010](http://software.intel.com/sites/landingpage/pintool/downloads/pin-2.13-65163-msvc10-windows.zip)
30+
2. Extract the ZIP
31+
3. Clone Sulo to `pin-2.13-65163-msvc10-windows\source\tools\Sulo`
32+
4. Open `sulo_vs2010.sln` and build the solution
33+
34+
Plugins
35+
-------
36+
37+
Sulo comes with three plugins:
38+
39+
1. Call tracer - logs all ActionScript method calls, including arguments and return values
40+
2. Flash dumper - dumps Flash objects loaded with Loader.loadBytes() to disk
41+
3. SecureSWF - logs decrypted strings from secureSWF-protected files
42+
43+
Creating your own plugin is easy: just inherit your class from `ISuloPlugin`, implement the virtual methods, and add the object to `m_plugins` in `SuloPluginManager::init()`.
44+
45+
Instrumenting Flash Player with Sulo
46+
------------------------------------
47+
48+
```
49+
pin.exe -t source\tools\sulo\Debug\sulo.dll -- "C:\path\to\Adobe\Flash\Player.exe"
50+
```
51+
52+
Command-line options
53+
--------------------
54+
55+
| Option | Default | Plugin | Explanation |
56+
|--------|---------|--------|--------------|
57+
|fast | false | General | Enables faster analysis by disabling call trace logging |
58+
|early_tracing | false | Call tracer | Start logging ActionScript method calls as early as possible (already before any calls from the actual Flash) |
59+
|tracefile | "calltrace.txt" | Call tracer | Filename for storing the call trace |
60+
|flash_dump_prefix | "dumped" | Flash dumper | Filename prefix for dumped Flash objects |
61+
|secureswf | "" | SecureSWF | Name of the string secureSWF decryption method |
62+
63+
64+
License
65+
-------
66+
67+
[Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)

‎main.cpp

Lines changed: 381 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,381 @@
1+
/*
2+
Copyright 2014 F-Secure
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#include "ASMethodInfo.h"
18+
#include "FlashPlayerConfigBuilder.h"
19+
#include "Logger.h"
20+
#include "SuloPluginManager.h"
21+
22+
#include "pin.h"
23+
24+
#include <iostream>
25+
#include <map>
26+
27+
28+
// Pin uses some base types that conflict with Windows types,
29+
// see: https://software.intel.com/sites/landingpage/pintool/docs/49306/Pin/html/index.html#namespace
30+
namespace WINDOWS
31+
{
32+
#include <windows.h>
33+
}
34+
35+
36+
// Flash Player config: all RVAs, data structure offfsets, etc.
37+
static Config* config = NULL;
38+
39+
// Map of addresses of methods that have been verified
40+
static map<ADDRINT,bool> verified;
41+
42+
// Whether the return address should be instrumented
43+
static map<ADDRINT,ADDRINT> returnAddressToInstument;
44+
45+
// Addresses that verified methods are known to return to
46+
static map<ADDRINT,bool> knownVerifiedMethodReturnAddress;
47+
48+
// Whether to log the return value or not. The last item in the vector is the latest call, the first the oldest
49+
static map<ADDRINT,vector<bool>*> logReturnValue;
50+
51+
// Fast mode uses these to store the return address that should be instrumented
52+
ADDRINT interestingReturnAddress = NULL;
53+
ADDRINT stackPtrInterestingReturnAddress = NULL;
54+
55+
// These are used to help PIN inline some of the analysis call.
56+
// If the value is true, the method is *potential* for analyzing (i.e. can have false positives)
57+
#define PRIME (99991)
58+
static bool potentialVerifiedMethod[PRIME];
59+
static bool potentialVerifiedMethodReturnAddress[PRIME];
60+
61+
62+
// General commandline options
63+
KNOB<bool> KnobFast(KNOB_MODE_WRITEONCE, "pintool", "fast", "false", "Runs plugins but no call trace generation");
64+
65+
// Commandline options for call tracer plugin
66+
KNOB<bool> KnobCallTracerEarlyTracing(KNOB_MODE_WRITEONCE, "pintool", "early_tracing", "false", "Start logging before actual Flash code runs?");
67+
KNOB<string> KnobCallTracerTraceFile(KNOB_MODE_WRITEONCE, "pintool", "tracefile", "calltrace.txt", "Call trace filename");
68+
69+
// Commandline options for Flash dumper plugin
70+
KNOB<string> KnobFlashDumperFilePrefix(KNOB_MODE_WRITEONCE, "pintool", "flash_dump_prefix", "dumped", "Filename prefix for dumped Flash objects");
71+
72+
// Commandline options for SecureSWF plugin
73+
KNOB<string> KnobSecureSWFMethodName(KNOB_MODE_WRITEONCE, "pintool", "secureswf", "", "Name of the string decryption method");
74+
75+
76+
// Print help message
77+
INT32 Usage()
78+
{
79+
cerr << "This Pintool instruments Adobe Flash Player and logs calls to all ActionScript methods." << endl << endl;
80+
cerr << KNOB_BASE::StringKnobSummary() << endl;
81+
return -1;
82+
}
83+
84+
85+
// Mark the JITed the interpreted method as verified so we know to instrument it
86+
VOID InterpretedMethodVerified(ADDRINT esi)
87+
{
88+
UINT32* methodInfo = (UINT32*)esi;
89+
ADDRINT addr = methodInfo[config->invokerOffsetInMethodInfo/sizeof(UINT32)];
90+
verified[addr] = true;
91+
potentialVerifiedMethod[addr%PRIME] = true;
92+
}
93+
94+
95+
// Mark the JITed method as verified so we know to instrument it
96+
VOID JITedMethodVerified(ADDRINT eax)
97+
{
98+
// EAX holds the address of the method
99+
verified[eax] = true;
100+
potentialVerifiedMethod[eax%PRIME] = true;
101+
}
102+
103+
104+
// This can have false positives, i.e. call is actually not worth analyzing.
105+
// PIN can inline this code, resulting in better performance
106+
ADDRINT ShouldCallBeAnalyzed(UINT32* esp, ADDRINT ret_addr, ADDRINT dest)
107+
{
108+
return (potentialVerifiedMethod[dest%PRIME] + potentialVerifiedMethodReturnAddress[ret_addr%PRIME]);
109+
}
110+
111+
112+
VOID MethodCallAnalysisFast(UINT32* esp, ADDRINT ret_addr, ADDRINT dest)
113+
{
114+
// Perform the necessary checks to filter out ShouldCallBeAnalyzed false positives
115+
if (verified.find(dest) == verified.end() && knownVerifiedMethodReturnAddress.find(ret_addr) == knownVerifiedMethodReturnAddress.end())
116+
{
117+
return;
118+
}
119+
120+
UINT32* methodEnv = (UINT32*)esp[0];
121+
UINT32 argc = esp[1];
122+
UINT32* argv = (UINT32*)esp[2];
123+
124+
UINT32* pMethodInfo = (UINT32*)methodEnv[config->methodInfoOffsetInMethodEnv/4];
125+
ASMethodInfo* mi = ASMethodInfo::create(pMethodInfo);
126+
string fullMethodName = mi->getMethodNameWithTraits();
127+
128+
bool shouldLogReturnValue = SuloPluginManager::beforeMethodCall(mi, fullMethodName, argc, argv);
129+
if (shouldLogReturnValue)
130+
{
131+
interestingReturnAddress = ret_addr;
132+
stackPtrInterestingReturnAddress = (ADDRINT)esp;
133+
}
134+
}
135+
136+
137+
VOID MethodCallAnalysis(UINT32* esp, ADDRINT ret_addr, ADDRINT dest)
138+
{
139+
// Perform the necessary checks to filter out ShouldCallBeAnalyzed false positives
140+
if (verified.find(dest) == verified.end() && knownVerifiedMethodReturnAddress.find(ret_addr) == knownVerifiedMethodReturnAddress.end())
141+
{
142+
return;
143+
}
144+
145+
knownVerifiedMethodReturnAddress[ret_addr] = true;
146+
potentialVerifiedMethodReturnAddress[ret_addr%PRIME] = true;
147+
148+
// This is not a call to verified method...
149+
if (verified.find(dest) == verified.end())
150+
{
151+
// ...but we'e seen calls to verified methods from this same address earlier,
152+
// so let's skip the return value
153+
if (logReturnValue.find(ret_addr) != logReturnValue.end())
154+
{
155+
if (logReturnValue[ret_addr] == NULL)
156+
{
157+
logReturnValue[ret_addr] = new vector<bool>;
158+
}
159+
logReturnValue[ret_addr]->push_back(false);
160+
}
161+
return;
162+
}
163+
164+
if (logReturnValue[ret_addr] == NULL)
165+
{
166+
logReturnValue[ret_addr] = new vector<bool>;
167+
}
168+
logReturnValue[ret_addr]->push_back(true);
169+
170+
UINT32* methodEnv = (UINT32*)esp[0];
171+
UINT32 argc = esp[1];
172+
UINT32* argv = (UINT32*)esp[2];
173+
174+
UINT32* pMethodInfo = (UINT32*)methodEnv[config->methodInfoOffsetInMethodEnv/4];
175+
176+
// Read/parse the full method name
177+
ASMethodInfo* mi = ASMethodInfo::create(pMethodInfo);
178+
string fullMethodName = mi->getMethodNameWithTraits();
179+
180+
SuloPluginManager::beforeMethodCall(mi, fullMethodName, argc, argv);
181+
}
182+
183+
184+
ADDRINT ShouldReturnAddressBeAnalyzedFast(ADDRINT ret_addr)
185+
{
186+
// This is NULL if we are not interested in logging the return value
187+
return interestingReturnAddress;
188+
}
189+
190+
191+
ADDRINT ShouldReturnAddressBeAnalyzed(ADDRINT ret_addr)
192+
{
193+
if (logReturnValue.find(ret_addr) == logReturnValue.end())
194+
{
195+
return 0;
196+
}
197+
198+
if (logReturnValue[ret_addr] == NULL)
199+
{
200+
return 0;
201+
}
202+
203+
if (logReturnValue[ret_addr]->size() == 0)
204+
{
205+
return 0;
206+
}
207+
208+
return 1;
209+
}
210+
211+
212+
VOID ReturnValueAnalysisFast(ADDRINT ret_addr, UINT32 eax, ADDRINT esp)
213+
{
214+
if (ret_addr != interestingReturnAddress || esp != stackPtrInterestingReturnAddress)
215+
{
216+
return;
217+
}
218+
219+
interestingReturnAddress = NULL;
220+
SuloPluginManager::afterMethodCall(eax);
221+
}
222+
223+
224+
VOID ReturnValueAnalysis(ADDRINT ret_addr, UINT32 eax, ADDRINT esp)
225+
{
226+
bool log = logReturnValue[ret_addr]->back();
227+
228+
if (log)
229+
{
230+
SuloPluginManager::afterMethodCall(eax);
231+
}
232+
233+
logReturnValue[ret_addr]->pop_back();
234+
}
235+
236+
237+
238+
// Pin calls this function before a code sequence is executed for the first time
239+
VOID TraceCalls(INS ins, VOID *v)
240+
{
241+
// If we don't have a proper config, we cannot instrument anything
242+
if (config == NULL)
243+
{
244+
return;
245+
}
246+
247+
ADDRINT addr = INS_Address(ins);
248+
IMG img = IMG_FindByAddress(addr);
249+
250+
// We are interested only calls from the JITted code. That code is not part of any valid image
251+
if (IMG_Valid(img) && img != config->img)
252+
{
253+
return;
254+
}
255+
256+
// We don't know the origins of the calls (only the targets) so we need to instrument every call
257+
if (INS_IsCall(ins))
258+
{
259+
bool ok = false;
260+
261+
if (INS_RegRContain(ins, REG_EAX) || INS_RegRContain(ins, REG_EDX))
262+
{
263+
ok = true;
264+
}
265+
else if (INS_IsDirectCall(ins))
266+
{
267+
ADDRINT target_addr = INS_DirectBranchOrCallTargetAddress(ins);
268+
IMG target_img = IMG_FindByAddress(target_addr);
269+
if (!IMG_Valid(img) || img == config->img)
270+
{
271+
ok = true;
272+
}
273+
}
274+
275+
if (ok)
276+
{
277+
// Select which call analysis function to use depending on whether we are in fast mode
278+
AFUNPTR analysisFunc = (AFUNPTR)MethodCallAnalysis;
279+
if (KnobFast.Value())
280+
{
281+
analysisFunc = (AFUNPTR)MethodCallAnalysisFast;
282+
}
283+
284+
ADDRINT ret_addr = INS_NextAddress(ins);
285+
INS_InsertIfCall(ins, IPOINT_BEFORE, (AFUNPTR)ShouldCallBeAnalyzed, IARG_FUNCARG_CALLSITE_REFERENCE, 0, IARG_ADDRINT, ret_addr, IARG_BRANCH_TARGET_ADDR, IARG_END);
286+
INS_InsertThenCall(ins, IPOINT_BEFORE, analysisFunc, IARG_FUNCARG_CALLSITE_REFERENCE, 0, IARG_ADDRINT, ret_addr, IARG_BRANCH_TARGET_ADDR, IARG_END);
287+
288+
returnAddressToInstument[ret_addr] = true;
289+
return;
290+
}
291+
}
292+
293+
if (returnAddressToInstument.find(addr) != returnAddressToInstument.end())
294+
{
295+
// Select which call analysis function to use depending on whether we are in fast mode
296+
AFUNPTR analysisFuncIf = (AFUNPTR)ShouldReturnAddressBeAnalyzed;
297+
AFUNPTR analysisFuncThen = (AFUNPTR)ReturnValueAnalysis;
298+
if (KnobFast.Value())
299+
{
300+
analysisFuncIf = (AFUNPTR)ShouldReturnAddressBeAnalyzedFast;
301+
analysisFuncThen = (AFUNPTR)ReturnValueAnalysisFast;
302+
}
303+
304+
INS_InsertIfCall(ins, IPOINT_BEFORE, analysisFuncIf, IARG_ADDRINT, addr, IARG_END);
305+
INS_InsertThenCall(ins, IPOINT_BEFORE, analysisFuncThen, IARG_ADDRINT, addr, IARG_REG_VALUE, REG_EAX, IARG_FUNCARG_CALLSITE_REFERENCE, 0, IARG_END);
306+
return;
307+
}
308+
}
309+
310+
311+
// This routine is executed for each image
312+
VOID ImageLoad(IMG img, VOID *v)
313+
{
314+
if (!FlashPlayerConfigBuilder::instance().isSupportedFlashPlayer(img))
315+
{
316+
return;
317+
}
318+
319+
LOGF("Found supported Flash Player image: %s (0x%x - 0x%x)\n", IMG_Name(img).c_str(), IMG_LowAddress(img), IMG_HighAddress(img));
320+
config = FlashPlayerConfigBuilder::instance().getConfig();
321+
322+
// config->setInterpRVA needs to be chosen in such way that
323+
// the value of _invoker can be found from [ESI+config->invinvokerOffsetInMethodInfookerOffset]
324+
RTN setInterp = RTN_CreateAt(config->loadOffset + config->setInterpRVA, "setInterp");
325+
326+
// config->setInterpRVA needs to be chosen in such way that
327+
// the value of _implGPR can be found from EAX
328+
RTN verifyOnCall = RTN_CreateAt(config->loadOffset + config->verifyOnCallRVA, "verifyOnCall");
329+
330+
if (setInterp == RTN_Invalid() || verifyOnCall == RTN_Invalid())
331+
{
332+
LOGF("Instrumenting Flash Player failed. Check setInterp and verifyOnCall RVAs in config.\n");
333+
return;
334+
}
335+
336+
RTN_Open(setInterp);
337+
RTN_InsertCall(setInterp, IPOINT_BEFORE, (AFUNPTR)InterpretedMethodVerified, IARG_REG_VALUE, REG_ESI, IARG_END);
338+
RTN_Close(setInterp);
339+
340+
RTN_Open(verifyOnCall);
341+
RTN_InsertCall(verifyOnCall, IPOINT_AFTER, (AFUNPTR)JITedMethodVerified, IARG_REG_VALUE, REG_EAX, IARG_END);
342+
RTN_Close(verifyOnCall);
343+
344+
// Register TraceCalls to be called to instrument instructions
345+
INS_AddInstrumentFunction(TraceCalls, 0);
346+
}
347+
348+
349+
// This function is called when the instrumented application exits
350+
VOID Fini(INT32 code, VOID *v)
351+
{
352+
SuloPluginManager::uninit();
353+
LOGF("[END]\n");
354+
}
355+
356+
357+
int main(int argc, char* argv[])
358+
{
359+
// This is needed for the RTN_* functions
360+
PIN_InitSymbols();
361+
362+
// Initialize Pin
363+
if (PIN_Init(argc,argv))
364+
{
365+
return Usage();
366+
}
367+
368+
// Now that we have access to commandline parameters, initialize the plugins
369+
SuloPluginManager::init();
370+
371+
// Register ImageLoad to be called when an image is loaded
372+
IMG_AddInstrumentFunction(ImageLoad, 0);
373+
374+
// Register Fini to be called when the application exists
375+
PIN_AddFiniFunction(Fini, 0);
376+
377+
// Start the program, never returns
378+
PIN_StartProgram();
379+
380+
return 0;
381+
}

‎plugins/CallTracerPlugin.cpp

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/*
2+
Copyright 2014 F-Secure
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#include "ASString.h"
18+
#include "ASMethodInfo.h"
19+
#include "CallTracerPlugin.h"
20+
#include "Logger.h"
21+
22+
namespace WINDOWS
23+
{
24+
#include <windows.h>
25+
}
26+
27+
28+
// Commandline options for call tracer plugin
29+
extern KNOB<bool> KnobCallTracerEarlyTracing;
30+
extern KNOB<string> KnobCallTracerTraceFile;
31+
32+
33+
CallTracerPlugin::CallTracerPlugin() :
34+
m_traceLoggingEnabled(KnobCallTracerEarlyTracing.Value()),
35+
m_callDepth(0)
36+
{
37+
m_traceFile.open(KnobCallTracerTraceFile.Value().c_str());
38+
}
39+
40+
41+
CallTracerPlugin::~CallTracerPlugin()
42+
{
43+
m_traceFile.close();
44+
}
45+
46+
47+
bool CallTracerPlugin::beforeMethodCall(ASMethodInfo* mi, string methodName, UINT32 argc, UINT32* argv)
48+
{
49+
// Save this so we can check the return value type
50+
m_mi = mi;
51+
52+
m_traceFile << format("\n%s%s ()\n", string(m_callDepth, '\t').c_str(), methodName.c_str());
53+
54+
// Is call trace logging (already) enabled?
55+
if (m_traceLoggingEnabled)
56+
{
57+
m_traceFile << format("%sthis: 0x%x\n", string(m_callDepth+1, '\t').c_str(), argv[0]);
58+
59+
// Get parameter types
60+
const vector<string>* parameterTypes = mi->getParameterTypes();
61+
string paramType;
62+
63+
// Print the actual arguments
64+
for (UINT32 i=0; i < argc; i++)
65+
{
66+
if (i >= parameterTypes->size())
67+
{
68+
paramType = "null";
69+
}
70+
else
71+
{
72+
paramType = parameterTypes->at(i);
73+
}
74+
75+
if (paramType == "String")
76+
{
77+
ASString* s = ASString::create((UINT32*)argv[i+1]);
78+
if (s != NULL)
79+
{
80+
m_traceFile << format("%sarg %d: \"%s\"\n", string(m_callDepth+1, '\t').c_str(), i, s->getString().c_str());
81+
continue;
82+
}
83+
}
84+
85+
m_traceFile << format("%sarg %d: 0x%x : %s\n", string(m_callDepth+1, '\t').c_str(), i, argv[i+1], paramType.c_str());
86+
}
87+
}
88+
else if (!m_traceLoggingEnabled && methodName == "flash.display::Sprite/constructChildren")
89+
{
90+
// We can start logging from the next method call
91+
m_traceLoggingEnabled = true;
92+
}
93+
94+
m_callDepth++;
95+
return false;
96+
}
97+
98+
99+
void CallTracerPlugin::afterMethodCall(UINT32 retVal)
100+
{
101+
m_callDepth--;
102+
103+
string type = m_mi->getReturnValueType();
104+
105+
if (type == "String")
106+
{
107+
ASString* s = ASString::create((UINT32*)retVal);
108+
if (s != NULL)
109+
{
110+
m_traceFile << format("%sReturned: \"%s\" (call depth: %d)\n", string(m_callDepth, '\t').c_str(), s->getString().c_str(), m_callDepth);
111+
return;
112+
}
113+
}
114+
115+
m_traceFile << format("%sReturned: 0x%x : %s (call depth: %d)\n", string(m_callDepth, '\t').c_str(), retVal, type.c_str(), m_callDepth);
116+
}
117+
118+
119+
string CallTracerPlugin::format(char* fmt, ...)
120+
{
121+
va_list args;
122+
va_start(args, fmt);
123+
124+
int len = vsnprintf(NULL, 0, fmt, args) + 1;
125+
char* buf = (char*)malloc(len);
126+
127+
vsnprintf(buf, len-1, fmt, args);
128+
buf[len-1] = 0;
129+
130+
string s(buf);
131+
132+
free(buf);
133+
va_end(args);
134+
135+
return s;
136+
}

‎plugins/CallTracerPlugin.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
Copyright 2014 F-Secure
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#pragma once
18+
19+
#include "ISuloPlugin.h"
20+
#include "pin.H"
21+
22+
#include <fstream>
23+
#include <map>
24+
25+
class ASMethodInfo;
26+
27+
class CallTracerPlugin : public ISuloPlugin
28+
{
29+
public:
30+
CallTracerPlugin();
31+
~CallTracerPlugin();
32+
33+
bool beforeMethodCall(ASMethodInfo* mi, string methodName, UINT32 argc, UINT32* argv);
34+
void afterMethodCall(UINT32 retVal);
35+
36+
private:
37+
38+
string format(char* fmt, ...);
39+
40+
typedef struct CallEntry {
41+
string name;
42+
string params;
43+
string retval;
44+
vector<CallEntry*>* children;
45+
} CallEntry;
46+
47+
// Log call trace to this stream
48+
ofstream m_traceFile;
49+
50+
// This flag is used to prevent the logging of uninteresting method calls before the actual Flash file runs
51+
bool m_traceLoggingEnabled;
52+
53+
ASMethodInfo* m_mi;
54+
int m_callDepth;
55+
map<int,vector<vector<CallEntry*>*>*> levelToList;
56+
};
57+

‎plugins/FlashDumperPlugin.cpp

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
Copyright 2014 F-Secure
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#include "FlashDumperPlugin.h"
18+
#include "ASByteArray.h"
19+
#include "Logger.h"
20+
21+
#include <fstream>
22+
23+
namespace WINDOWS
24+
{
25+
#include <windows.h>
26+
}
27+
28+
29+
// Commandline options for Flash dumper plugin
30+
extern KNOB<string> KnobFlashDumperFilePrefix;
31+
32+
33+
FlashDumperPlugin::FlashDumperPlugin() :
34+
m_filePrefix(KnobFlashDumperFilePrefix.Value()),
35+
m_dumpedFlashCount(0)
36+
{
37+
}
38+
39+
40+
bool FlashDumperPlugin::beforeMethodCall(ASMethodInfo* mi, string methodName, UINT32 argc, UINT32* argv)
41+
{
42+
if (methodName != "flash.display::Loader/loadBytes")
43+
{
44+
return false;
45+
}
46+
47+
ASByteArray* ba = ASByteArray::create((UINT32*)argv[1]);
48+
if (ba == NULL)
49+
{
50+
return false;
51+
}
52+
53+
UINT8* data = ba->getData();
54+
UINT32 nBytes = ba->getDataLength();
55+
56+
LOGF("Dumping flash from 0x%x, %d bytes\n", data, nBytes);
57+
58+
char filename[MAX_PATH+1];
59+
_snprintf(filename, MAX_PATH, "%s_flash_%u.bin", m_filePrefix.c_str(), m_dumpedFlashCount);
60+
m_dumpedFlashCount++;
61+
//LOGF("Dumping flash to %s\n", filename);
62+
ofstream flashFile(filename, ios::out | ios::binary);
63+
flashFile.write((const char*)data, nBytes);
64+
flashFile.close();
65+
66+
LOGF("Dumped flash to %s\n", filename);
67+
68+
return false;
69+
}
70+
71+
72+
void FlashDumperPlugin::afterMethodCall(UINT32 retVal)
73+
{
74+
return;
75+
}
76+
77+
78+
void FlashDumperPlugin::dumpFlashToDisk(UINT8* data, UINT32 nBytes)
79+
{
80+
}

‎plugins/FlashDumperPlugin.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
Copyright 2014 F-Secure
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#pragma once
18+
19+
#include "ISuloPlugin.h"
20+
#include "pin.H"
21+
22+
class FlashDumperPlugin : public ISuloPlugin
23+
{
24+
public:
25+
FlashDumperPlugin();
26+
27+
bool beforeMethodCall(ASMethodInfo* mi, string methodName, UINT32 argc, UINT32* argv);
28+
void afterMethodCall(UINT32 retVal);
29+
30+
private:
31+
void dumpFlashToDisk(UINT8* data, UINT32 nBytes);
32+
33+
string m_filePrefix;
34+
35+
// Running count for numbering the dumped Flash files
36+
int m_dumpedFlashCount;
37+
};
38+

‎plugins/ISuloPlugin.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
Copyright 2014 F-Secure
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#pragma once
18+
19+
#include "pin.H"
20+
21+
class ASMethodInfo;
22+
23+
class ISuloPlugin
24+
{
25+
public:
26+
virtual ~ISuloPlugin() {};
27+
virtual bool beforeMethodCall(ASMethodInfo* mi, string methodName, UINT32 argc, UINT32* argv) = 0;
28+
virtual void afterMethodCall(UINT32 retVal) = 0;
29+
};
30+

‎plugins/SecureSWFPlugin.cpp

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
Copyright 2014 F-Secure
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#include "SecureSWFPlugin.h"
18+
#include "ASMethodInfo.h"
19+
#include "ASString.h"
20+
#include "Logger.h"
21+
22+
// General commandline options
23+
extern KNOB<bool> KnobFast;
24+
25+
// Commandline options for call tracer plugin
26+
extern KNOB<string> KnobSecureSWFMethodName;
27+
28+
SecureSWFPlugin::SecureSWFPlugin() :
29+
m_methodName(KnobSecureSWFMethodName.Value()),
30+
m_callDepth(0),
31+
m_log(false),
32+
m_fast(KnobFast.Value())
33+
{
34+
}
35+
36+
37+
bool SecureSWFPlugin::beforeMethodCall(ASMethodInfo* mi, string methodName, UINT32 argc, UINT32* argv)
38+
{
39+
// We need to call depth information only in normal mode
40+
if (!m_fast)
41+
{
42+
m_callDepth++;
43+
}
44+
45+
if (methodName.find(m_methodName) != string::npos && argc == 1)
46+
{
47+
string returnValueType = mi->getReturnValueType();
48+
if (returnValueType == "String")
49+
{
50+
// Store the ID of the encrypted string so we can print it when
51+
// we get the decrypted string
52+
m_stringId = (int)argv[1];
53+
m_logRetValCallDepth = m_callDepth-1;
54+
m_log = true;
55+
return true;
56+
}
57+
}
58+
return false;
59+
}
60+
61+
62+
void SecureSWFPlugin::afterMethodCall(UINT32 retVal)
63+
{
64+
// We need to call depth information only in normal mode
65+
if (!m_fast)
66+
{
67+
m_callDepth--;
68+
}
69+
70+
if (!m_log)
71+
{
72+
return;
73+
}
74+
75+
if (!m_fast && m_callDepth != m_logRetValCallDepth)
76+
{
77+
return;
78+
}
79+
80+
m_log = false;
81+
82+
ASString* s = ASString::create((UINT32*)retVal);
83+
if (s != NULL)
84+
{
85+
LOGF("[secureswf] String ID: %d, decrypted string: \"%s\"\n", m_stringId, s->getString().c_str());
86+
}
87+
return;
88+
}

‎plugins/SecureSWFPlugin.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
Copyright 2014 F-Secure
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#pragma once
18+
19+
#include "ISuloPlugin.h"
20+
#include "pin.H"
21+
22+
class SecureSWFPlugin : public ISuloPlugin
23+
{
24+
public:
25+
SecureSWFPlugin();
26+
27+
bool beforeMethodCall(ASMethodInfo* mi, string methodName, UINT32 argc, UINT32* argv);
28+
void afterMethodCall(UINT32 retVal);
29+
30+
private:
31+
string m_methodName;
32+
int m_callDepth;
33+
int m_logRetValCallDepth;
34+
bool m_log;
35+
int m_stringId;
36+
37+
// The logic is slightly different in normal and fast mode
38+
bool m_fast;
39+
};
40+

‎plugins/SuloPluginManager.cpp

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
Copyright 2014 F-Secure
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#include "SuloPluginManager.h"
18+
#include "CallTracerPlugin.h"
19+
#include "FlashDumperPlugin.h"
20+
#include "SecureSWFPlugin.h"
21+
22+
#include <iostream>
23+
24+
extern KNOB<bool> KnobFast;
25+
extern KNOB<string> KnobSecureSWFMethodName;
26+
27+
vector<ISuloPlugin*> SuloPluginManager::m_plugins;
28+
29+
void SuloPluginManager::init(void)
30+
{
31+
// Call tracer is disabled in fast mode
32+
if (!KnobFast.Value())
33+
{
34+
m_plugins.push_back(new CallTracerPlugin());
35+
}
36+
37+
if (!KnobSecureSWFMethodName.Value().empty())
38+
{
39+
m_plugins.push_back(new SecureSWFPlugin());
40+
}
41+
42+
m_plugins.push_back(new FlashDumperPlugin());
43+
}
44+
45+
46+
bool SuloPluginManager::beforeMethodCall(ASMethodInfo* mi, string methodName, UINT32 argc, UINT32* argv)
47+
{
48+
bool logReturnAddress = false;
49+
for (std::vector<ISuloPlugin*>::iterator it = m_plugins.begin(); it != m_plugins.end(); ++it)
50+
{
51+
bool r = (*it)->beforeMethodCall(mi, methodName, argc, argv);
52+
if (r)
53+
{
54+
logReturnAddress = true;
55+
}
56+
}
57+
58+
return logReturnAddress;
59+
}
60+
61+
62+
void SuloPluginManager::afterMethodCall(UINT32 retVal)
63+
{
64+
for (std::vector<ISuloPlugin*>::iterator it = m_plugins.begin(); it != m_plugins.end(); ++it)
65+
{
66+
(*it)->afterMethodCall(retVal);
67+
}
68+
}
69+
70+
71+
void SuloPluginManager::uninit(void)
72+
{
73+
for (std::vector<ISuloPlugin*>::iterator it = m_plugins.begin(); it != m_plugins.end(); ++it)
74+
{
75+
delete *it;
76+
}
77+
}

‎plugins/SuloPluginManager.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
Copyright 2014 F-Secure
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
#pragma once
18+
19+
#include "ISuloPlugin.h"
20+
#include "pin.H"
21+
22+
#include <vector>
23+
24+
class ASMethodInfo;
25+
26+
class SuloPluginManager
27+
{
28+
public:
29+
static void init(void);
30+
static bool beforeMethodCall(ASMethodInfo* mi, string methodName, UINT32 argc, UINT32* argv);
31+
static void afterMethodCall(UINT32 retVal);
32+
static void uninit(void);
33+
34+
private:
35+
SuloPluginManager();
36+
SuloPluginManager(SuloPluginManager const&);
37+
void operator=(SuloPluginManager const&);
38+
39+
static vector<ISuloPlugin*> m_plugins;
40+
};

‎sulo_VS2010.sln

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 11.00
3+
# Visual Studio 2010
4+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sulo", "sulo_VS2010.vcxproj", "{639EF517-FCFC-408E-9500-71F0DC0458DB}"
5+
EndProject
6+
Global
7+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
8+
Debug|Win32 = Debug|Win32
9+
Debug|x64 = Debug|x64
10+
Release|Win32 = Release|Win32
11+
Release|x64 = Release|x64
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{639EF517-FCFC-408E-9500-71F0DC0458DB}.Debug|Win32.ActiveCfg = Debug|Win32
15+
{639EF517-FCFC-408E-9500-71F0DC0458DB}.Debug|Win32.Build.0 = Debug|Win32
16+
{639EF517-FCFC-408E-9500-71F0DC0458DB}.Debug|x64.ActiveCfg = Debug|x64
17+
{639EF517-FCFC-408E-9500-71F0DC0458DB}.Debug|x64.Build.0 = Debug|x64
18+
{639EF517-FCFC-408E-9500-71F0DC0458DB}.Release|Win32.ActiveCfg = Release|Win32
19+
{639EF517-FCFC-408E-9500-71F0DC0458DB}.Release|Win32.Build.0 = Release|Win32
20+
{639EF517-FCFC-408E-9500-71F0DC0458DB}.Release|x64.ActiveCfg = Release|x64
21+
{639EF517-FCFC-408E-9500-71F0DC0458DB}.Release|x64.Build.0 = Release|x64
22+
EndGlobalSection
23+
GlobalSection(SolutionProperties) = preSolution
24+
HideSolutionNode = FALSE
25+
EndGlobalSection
26+
EndGlobal

‎sulo_VS2010.vcxproj

Lines changed: 281 additions & 0 deletions
Large diffs are not rendered by default.

‎sulo_VS2010.vcxproj.filters

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<ItemGroup>
4+
<ClCompile Include="ASByteArray.cpp" />
5+
<ClCompile Include="ASMethodInfo.cpp" />
6+
<ClCompile Include="ASMultiname.cpp" />
7+
<ClCompile Include="ASString.cpp" />
8+
<ClCompile Include="main.cpp" />
9+
<ClCompile Include="ASTraits.cpp" />
10+
<ClCompile Include="plugins\CallTracerPlugin.cpp">
11+
<Filter>plugins</Filter>
12+
</ClCompile>
13+
<ClCompile Include="plugins\FlashDumperPlugin.cpp">
14+
<Filter>plugins</Filter>
15+
</ClCompile>
16+
<ClCompile Include="plugins\SuloPluginManager.cpp">
17+
<Filter>plugins</Filter>
18+
</ClCompile>
19+
<ClCompile Include="FlashPlayerConfigBuilder.cpp" />
20+
<ClCompile Include="plugins\SecureSWFPlugin.cpp">
21+
<Filter>plugins</Filter>
22+
</ClCompile>
23+
</ItemGroup>
24+
<ItemGroup>
25+
<ClInclude Include="ASByteArray.h" />
26+
<ClInclude Include="ASMethodInfo.h" />
27+
<ClInclude Include="ASMultiname.h" />
28+
<ClInclude Include="ASString.h" />
29+
<ClInclude Include="ASTraits.h" />
30+
<ClInclude Include="FlashPlayerConfigBuilder.h" />
31+
<ClInclude Include="Logger.h" />
32+
<ClInclude Include="plugins\CallTracerPlugin.h">
33+
<Filter>plugins</Filter>
34+
</ClInclude>
35+
<ClInclude Include="plugins\FlashDumperPlugin.h">
36+
<Filter>plugins</Filter>
37+
</ClInclude>
38+
<ClInclude Include="plugins\ISuloPlugin.h">
39+
<Filter>plugins</Filter>
40+
</ClInclude>
41+
<ClInclude Include="plugins\SuloPluginManager.h">
42+
<Filter>plugins</Filter>
43+
</ClInclude>
44+
<ClInclude Include="plugins\SecureSWFPlugin.h">
45+
<Filter>plugins</Filter>
46+
</ClInclude>
47+
</ItemGroup>
48+
<ItemGroup>
49+
<Filter Include="plugins">
50+
<UniqueIdentifier>{78ea4d96-4e7c-4593-a751-c6475609c35b}</UniqueIdentifier>
51+
</Filter>
52+
</ItemGroup>
53+
</Project>

0 commit comments

Comments
 (0)
Please sign in to comment.