Package: skrapa
SkrapaSkrapa is a zero dependency and customizable Python library for scanning Windows and Linux process memory.ContentsInstallationQuickstartHow it worksUsageScanning a PIDScan using YARAPage filtersFeaturesInstallationInstallation can be done usingpip:$pipinstallskrapaYou can also include YARA support by installing theyaravariant:$pipinstallskrapa[yara]QuickstartStart scanning with a given process ID after installing the library:pythonexamples/scan_pid.py--pid8320--hex0000488B0557F402004833C448894424--protectPAGE_EXECUTE_READ--alloc-protectPAGE_EXECUTE_WRITECOPY--typeMEM_IMAGE--stateMEM_COMMITHow it worksSkrapa differs slightly from the traditional sense of memory scanning in that it allows you to filter on specific memory attributes, which can greatly reduce the time it takes to scan process memory.On the Windows and Linux platforms the memory regions assigned to a specific process each hold their own set of permissions. These permissions can basically be boiled down to the permissions we know and love:READ,WRITE, andEXECUTE. Within process memory these permissions can be combined as some process memory needs to be readable as well as executable when we want to execute code from this memory region.The API was designed to be transparent so it doesn't matter if the script was written for Windows or Linux (with the single exception for a permission that is only available on Windows).Warningto effectively scan the memory space on Windows or Linux you will need administrative privileges on the target system.UsageScanning a PIDLet's try to scan for the hex pattern of0000488B0557F402004833C448894424on Windows. To speed up the scanning process we assume that the following memory permissions are set for the region that the pattern should exist in:Protect:PAGE_EXECUTE_READAllocation Protect:PAGE_EXECUTE_WRITECOPYType:MEM_IMAGEState:MEM_COMMITAny memory region that does not have these permissions set will be exempt from the matching process, increasing the speed of the scan. The boilerplate code for such a scan would look something like this:fromskrapaimportAccessProtectionType,HexPattern,MemoryAttributes,scan_pidmem_attributes=MemoryAttributes(protect=AccessProtectionType.PAGE_EXECUTE_READ,allocation_protect=AccessProtectionType.PAGE_EXECUTE_WRITECOPY,type=AllocationType.MEM_IMAGE,state=AllocationType.MEM_COMMIT,)forhitinscan_pid(pid=8320,patterns=HexPattern("0000488B0557F402004833C448894424"),attributes=mem_attributes):print(hit)For each hit on the pattern we can look at the different attributes belonging to the process:Process name:hit.process.nameProcess path:hit.process.pathProcess architecture:hit.process.architectureOr for the associated memory region:Memory region start:hit.region_startMemory region size:hit.region_sizeMemory region end:hit.region_start + hit.region_sizeAddress of the match:hit.addressWe can read 128 bytes from the start of the pattern match because we might know there will be some interesting information after this pattern:fromskrapaimportread_process_memorymatch_content=read_process_memory(pid=8320,address=hit.address,size=128)You can then do whatever post processing you want on these bytes.Scan using YARANote: to use the YARA functionality of Skrapa, you'll need to haveyara-pythoninstalled. You can install this manually or runpip install skrapa[yara].We're continuing our search leveraging YARA to find a pattern in the process memory ofnotepad.exe. Using YARA rules with Skrapa is as easy as pointing to your YARA file containing the rule(s) you want to match within the process memory. The YARA rule we're using for this example is:rulel33t_notepad_rule{strings:$={0000488B0557F402004833C448894424}condition:anyofthem}We can use the YARA rule from above to find the pattern in the process memory:fromskrapaimportAccessProtectionType,MemoryAttributes,scan_pidtry:importyaraexceptImportError:logging.error("YARA Python module not found, install it with: pip install yara-python")exit(1)mem_attributes=MemoryAttributes(protect=AccessProtectionType.PAGE_EXECUTE_READ,allocation_protect=AccessProtectionType.PAGE_EXECUTE_WRITECOPY,type=AllocationType.MEM_IMAGE,state=AllocationType.MEM_COMMIT,)patterns=yara.compile(source="rule l33t_notepad { strings: $ ={0000488B0557F402004833C448894424}condition: any of them }")forhitinscan_pid(pid=8320,patterns=patterns,attributes=mem_attributes):print(hit)The results of the above scan can be used in the exact same manner as the previous example shown. If you'd rather load in a YARA from a specified file you can switch thesource=parameter of theyara.compilecall withfilepath=.Page filtersSkrapa allows users to define more complex memory filtering conditions by making use of a callback function. The callback function can also be used to check the size of the memory region before trying to match the given pattern.For this example we will define the followingpage_filterfunction that will first check if:The given region is bigger than0x300000and smaller than0x400000The given region does not have thePAGE_NOACCESSprotect attribute setThe given region has thePAGE_READWRITEprotect attribute setNote that we will not provide any of the memory attributes when using the abovepage_filterdefinition, instead we define every condition in the function:fromskrapaimportAccessProtectionType,HexPattern,MemoryAttributes,scan_piddefpage_filter(pageinfo)->bool:return(0x300000>pageinfo.size<=0x400000andpageinfo.attributes.protect.name!="PAGE_NOACCESS"andpageinfo.attributes.protect.name=="PAGE_READWRITE")mem_attributes=MemoryAttributes(protect=None,allocation_protect=None,type=None,state=None)forhitinscan_pid(pid=8320,patterns=HexPattern("0000488B0557F402004833C448894424"),attributes=mem_attributes,page_filter=page_filter):print(hit)We will now only receive hits if thepage_filterconditions were met.Check out theexamples/folder to quickly get started!FeaturesSupports x86 and x64 Windows and Linux platforms;Scan a single process by name or PID, or scan the entire memory space;Support for YARA signatures;Support for page filters for more complex conditions;