Files
2013-03-29 11:54:46 -04:00

148 lines
5.5 KiB
Python
Executable File

#/usr/bin/env python
import getopt
import struct
import immutils
from immlib import *
copyright="(C) Immunity, Inc."
DESC = "Dumps Acrobat Reader Cache state"
class AdobeHeap:
def __init__(self,AcroPool):
'''
AcroManagingPool (hardcoded address depens on version of the AcroRd32.dll)
From this address it's possible to access all managing structures of their custom heap implementation.
'''
self.AcroPool = AcroPool
self.imm = Debugger()
self.pAcroCacheList = []
self.CacheHeadersInfo = []
self.AcroManagingPool()
def AcroManagingPool(self):
self.AcroPool += 0xC #Reserved
self.mem = self.imm.readMemory(self.AcroPool,128) #Managing structures for AcroCache
self.lpCacheManaging = struct.unpack("32L",self.mem)
self.AcroPool += (0x90 - 0xC) #Header of the first AcroBlock
self.FirstAcroBlock = self.imm.readLong(self.AcroPool)
def CacheManager(self,addr):
self.AcroPool = self.imm.readMemory(addr,0x10)
(pAcroPool,pFreeBlocksList,pAcroCacheList,blocksize) = struct.unpack("4L",self.AcroPool)
self.imm.log("pAcroPool: 0x%08x pFreeBlocksList: 0x%08x pAcroCacheList: 0x%08x blocksize: 0x%08x" % (pAcroPool,pFreeBlocksList,pAcroCacheList,\
blocksize), address = pAcroCacheList)
return pAcroCacheList
def CacheHeader(self,addr):
self.AcroPool = self.imm.readMemory(addr,0x18)
(pCacheManager,allocatedBlocks,flag,blink,flink,size) = struct.unpack("6L",self.AcroPool)
self.imm.log("CacheManager: 0x%08x AllocatedBlocks: 0x%08x Flags: 0x%08x BLINK: 0x%08x FLINK: 0x%08x Size: 0x%08x" % (pCacheManager,allocatedBlocks\
,flag,blink,flink,size), address = addr)
return flink
def walkCache(self,addr):
isAcroBlock = False
isCache = False
flag = self.imm.readLong(addr+0x8)
if flag == 2:
isAcroBlock = True
size = self.imm.readLong(addr+0x18)
elif flag == 0:
isCache = True
size = self.imm.readLong(addr+0x14)
self.imm.log("")
self.imm.log("***Walking through 0x%08x bytes cache***"%size)
i = 0
while 1:
Flink = self.imm.readLong(addr+0x10)
AllocatedBlocks = self.imm.readLong(addr+0x04)
AcroBlockSize = self.imm.readLong(addr+0x14)
if not Flink:
self.imm.log("***Walk Done***")
break
if isCache:
self.imm.log("Cache[%d]: 0x%08x | Allocated Blocks: [%d/128]" % (i,addr,AllocatedBlocks), address = addr)
elif isAcroBlock:
self.imm.log("AcroBlock: 0x%08x | Size: 0x08%x" % (Flink,AcroBlockSize), address = Flink)
addr = Flink
i += 1
def getCacheManagers(self):
self.imm.log("")
self.imm.log("CacheManagers List:")
i=0
for x in self.lpCacheManaging:
self.imm.log("lpCacheManaging[%d]: 0x%08x" % (i,x))
i += 1
def getCacheManagersInfo(self):
self.imm.log("")
self.imm.log("[Cache Managers Info]")
for x in self.lpCacheManaging:
self.pAcroCacheList.append(self.CacheManager(x))
def getCacheHeaders(self):
self.imm.log("")
self.imm.log("[Cache Headers]")
for x in self.pAcroCacheList:
try:
self.CacheHeadersInfo.append(self.CacheHeader(x))
except:
pass
def dumpCache(self):
self.getCacheManagers()
self.getCacheManagersInfo()
self.getCacheHeaders()
self.pAcroCacheList.pop(0) #unused entry
for x in self.pAcroCacheList:
self.walkCache(x)
def DumpAcroBlocks(self):
addr = self.FirstAcroBlock
self.AcroPool = self.imm.readMemory(addr,0x18)
(pAcroPool,reserved,flag,blink,flink,size) = struct.unpack("6L",self.AcroPool)
self.walkCache(flink)
def usage(imm):
imm.log("!acrocache")
imm.log(" -c Dump AcroCache state")
imm.log(" -f CACHEBLOCKADDR Follow CacheBlocks of same size and show allocations count")
imm.log(" -b Dump AcroBlocks")
def main(args):
imm = Debugger()
pAcroManagingPool = 0x014D38A0 #Acrobat Reader 9.4.0
try:
AcroManagingPool = imm.readLong(pAcroManagingPool)
except:
return "Couldn't read from AcroManagingPool pointer. Are you on Reader 9.4.0?"
adobe = AdobeHeap(AcroManagingPool)
if not args:
usage(imm)
try:
opts, argo = getopt.getopt(args, "bcf:")
except getopt.GetoptError:
usage(imm)
for o,a in opts:
if o == "-f":
try:
adobe.walkCache(int(a, 16))
except ValueError, msg:
return "Invalid address: %s" % a
if o == "-b":
adobe.DumpAcroBlocks()
if o == "-c":
adobe.dumpCache()
return "done"