|
24 | 24 | from volatility3.framework.renderers import conversion |
25 | 25 | from volatility3.framework.symbols import generic |
26 | 26 | from volatility3.framework.symbols.windows.extensions import pool |
| 27 | +from volatility3.framework.symbols import windows |
27 | 28 |
|
28 | 29 | vollog = logging.getLogger(__name__) |
29 | 30 |
|
@@ -781,39 +782,133 @@ def get_peb(self) -> interfaces.objects.ObjectInterface: |
781 | 782 | ) |
782 | 783 | return peb |
783 | 784 |
|
| 785 | + def get_peb32(self) -> Optional[interfaces.objects.ObjectInterface]: |
| 786 | + """Constructs a PEB32 object""" |
| 787 | + if constants.BANG not in self.vol.type_name: |
| 788 | + raise ValueError( |
| 789 | + f"Invalid symbol table name syntax (no {constants.BANG} found)" |
| 790 | + ) |
| 791 | + |
| 792 | + # add_process_layer can raise InvalidAddressException. |
| 793 | + # if that happens, we let the exception propagate upwards |
| 794 | + proc_layer_name = self.add_process_layer() |
| 795 | + proc_layer = self._context.layers[proc_layer_name] |
| 796 | + |
| 797 | + # Determine if process is running under WOW64. |
| 798 | + if self.get_is_wow64(): |
| 799 | + proc = self.get_wow_64_process() |
| 800 | + else: |
| 801 | + return None |
| 802 | + # Confirm WoW64Process points to a valid process address |
| 803 | + if not proc_layer.is_valid(proc): |
| 804 | + raise exceptions.InvalidAddressException( |
| 805 | + proc_layer_name, proc, f"Invalid Wow64Process address at {self.Peb:0x}" |
| 806 | + ) |
| 807 | + |
| 808 | + # Leverage the context of existing symbol table to help configure |
| 809 | + # a new symbol table for 32-bit types |
| 810 | + sym_table = self.get_symbol_table_name() |
| 811 | + config_path = self._context.symbol_space[sym_table].config_path |
| 812 | + |
| 813 | + # Load the 32-bit types into a new symbol space |
| 814 | + # We use the WindowsKernelIntermedSymbols class to make |
| 815 | + # sure we get all the object helpers. For example, traversing |
| 816 | + # linked-lists. |
| 817 | + self._32bit_table_name = windows.WindowsKernelIntermedSymbols.create( |
| 818 | + self._context, config_path, "windows", "wow64" |
| 819 | + ) |
| 820 | + |
| 821 | + # windows 10 |
| 822 | + if self._context.symbol_space.has_type( |
| 823 | + sym_table + constants.BANG + "_EWOW64PROCESS" |
| 824 | + ): |
| 825 | + offset = proc.Peb |
| 826 | + |
| 827 | + # vista sp0-sp1 and 2003 sp1-sp2 |
| 828 | + elif self._context.symbol_space.has_type( |
| 829 | + sym_table + constants.BANG + "_WOW64_PROCESS" |
| 830 | + ): |
| 831 | + offset = proc.Wow64 |
| 832 | + |
| 833 | + else: |
| 834 | + offset = proc |
| 835 | + |
| 836 | + peb32 = self._context.object( |
| 837 | + f"{self._32bit_table_name}{constants.BANG}_PEB32", |
| 838 | + layer_name=proc_layer_name, |
| 839 | + offset=offset, |
| 840 | + ) |
| 841 | + return peb32 |
| 842 | + |
| 843 | + def set_types(self, peb) -> str: |
| 844 | + ldr_data = self._context.symbol_space.get_type( |
| 845 | + self._32bit_table_name + constants.BANG + "_PEB_LDR_DATA" |
| 846 | + ) |
| 847 | + peb.Ldr = peb.Ldr.cast("pointer", subtype=ldr_data) |
| 848 | + sym_table = self._32bit_table_name |
| 849 | + return sym_table |
| 850 | + |
784 | 851 | def load_order_modules(self) -> Iterable[interfaces.objects.ObjectInterface]: |
785 | 852 | """Generator for DLLs in the order that they were loaded.""" |
786 | | - |
787 | 853 | try: |
788 | | - peb = self.get_peb() |
789 | | - yield from peb.Ldr.InLoadOrderModuleList.to_list( |
790 | | - f"{self.get_symbol_table_name()}{constants.BANG}_LDR_DATA_TABLE_ENTRY", |
791 | | - "InLoadOrderLinks", |
792 | | - ) |
| 854 | + pebs = [ |
| 855 | + self.get_peb(), |
| 856 | + self.get_peb32(), |
| 857 | + ] |
| 858 | + for peb in pebs: |
| 859 | + if peb: |
| 860 | + sym_table = self.get_symbol_table_name() |
| 861 | + if peb.Ldr.vol.type_name.split(constants.BANG)[-1] == ( |
| 862 | + "unsigned long" |
| 863 | + ): |
| 864 | + sym_table = self.set_types(peb) |
| 865 | + yield from peb.Ldr.InLoadOrderModuleList.to_list( |
| 866 | + f"{sym_table}{constants.BANG}" + "_LDR_DATA_TABLE_ENTRY", |
| 867 | + "InLoadOrderLinks", |
| 868 | + ) |
793 | 869 | except exceptions.InvalidAddressException: |
794 | 870 | return None |
795 | 871 |
|
796 | 872 | def init_order_modules(self) -> Iterable[interfaces.objects.ObjectInterface]: |
797 | 873 | """Generator for DLLs in the order that they were initialized""" |
798 | 874 |
|
799 | 875 | try: |
800 | | - peb = self.get_peb() |
801 | | - yield from peb.Ldr.InInitializationOrderModuleList.to_list( |
802 | | - f"{self.get_symbol_table_name()}{constants.BANG}_LDR_DATA_TABLE_ENTRY", |
803 | | - "InInitializationOrderLinks", |
804 | | - ) |
| 876 | + pebs = [ |
| 877 | + self.get_peb(), |
| 878 | + self.get_peb32(), |
| 879 | + ] |
| 880 | + for peb in pebs: |
| 881 | + if peb: |
| 882 | + sym_table = self.get_symbol_table_name() |
| 883 | + if peb.Ldr.vol.type_name.split(constants.BANG)[-1] == ( |
| 884 | + "unsigned long" |
| 885 | + ): |
| 886 | + sym_table = self.set_types(peb) |
| 887 | + yield from peb.Ldr.InInitializationOrderModuleList.to_list( |
| 888 | + f"{sym_table}{constants.BANG}" + "_LDR_DATA_TABLE_ENTRY", |
| 889 | + "InInitializationOrderLinks", |
| 890 | + ) |
805 | 891 | except exceptions.InvalidAddressException: |
806 | 892 | return None |
807 | 893 |
|
808 | 894 | def mem_order_modules(self) -> Iterable[interfaces.objects.ObjectInterface]: |
809 | 895 | """Generator for DLLs in the order that they appear in memory""" |
810 | | - |
811 | 896 | try: |
812 | | - peb = self.get_peb() |
813 | | - yield from peb.Ldr.InMemoryOrderModuleList.to_list( |
814 | | - f"{self.get_symbol_table_name()}{constants.BANG}_LDR_DATA_TABLE_ENTRY", |
815 | | - "InMemoryOrderLinks", |
816 | | - ) |
| 897 | + pebs = [ |
| 898 | + self.get_peb(), |
| 899 | + self.get_peb32(), |
| 900 | + ] |
| 901 | + for peb in pebs: |
| 902 | + if peb: |
| 903 | + sym_table = self.get_symbol_table_name() |
| 904 | + if peb.Ldr.vol.type_name.split(constants.BANG)[-1] == ( |
| 905 | + "unsigned long" |
| 906 | + ): |
| 907 | + sym_table = self.set_types(peb) |
| 908 | + yield from peb.Ldr.InMemoryOrderModuleList.to_list( |
| 909 | + f"{sym_table}{constants.BANG}" + "_LDR_DATA_TABLE_ENTRY", |
| 910 | + "InMemoryOrderLinks", |
| 911 | + ) |
817 | 912 | except exceptions.InvalidAddressException: |
818 | 913 | return None |
819 | 914 |
|
|
0 commit comments