[Forensics-changes] [yara] 68/135: Implement imports() function and other small changes in PE module
Hilko Bengen
bengen at moszumanska.debian.org
Sat Jul 1 10:27:33 UTC 2017
This is an automated email from the git hooks/post-receive script.
bengen pushed a commit to annotated tag v3.1.0
in repository yara.
commit c4ae098c9dfe98324a1d7627dd8e36d8228fd038
Author: Victor M. Alvarez <plusvic at gmail.com>
Date: Tue Jul 22 13:20:47 2014 +0200
Implement imports() function and other small changes in PE module
---
libyara/include/yara/pe.h | 45 ++++++++
libyara/include/yara/utils.h | 1 +
libyara/modules/pe.c | 243 +++++++++++++++++++++++++++++++++++--------
3 files changed, 243 insertions(+), 46 deletions(-)
diff --git a/libyara/include/yara/pe.h b/libyara/include/yara/pe.h
index 52b2cb0..ce57734 100644
--- a/libyara/include/yara/pe.h
+++ b/libyara/include/yara/pe.h
@@ -281,6 +281,7 @@ typedef struct _IMAGE_SECTION_HEADER {
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;
+
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
#define IMAGE_SIZEOF_SECTION_HEADER 40
@@ -301,5 +302,49 @@ typedef struct _IMAGE_EXPORT_DIRECTORY {
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
+typedef struct _IMAGE_IMPORT_DESCRIPTOR {
+ union {
+ DWORD Characteristics;
+ DWORD OriginalFirstThunk;
+ } ;
+ DWORD TimeDateStamp;
+ DWORD ForwarderChain;
+ DWORD Name;
+ DWORD FirstThunk;
+
+} IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR;
+
+
+typedef struct _IMAGE_IMPORT_BY_NAME {
+ WORD Hint;
+ BYTE Name[1];
+
+} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;
+
+typedef struct _IMAGE_THUNK_DATA32 {
+ union {
+ DWORD ForwarderString;
+ DWORD Function;
+ DWORD Ordinal;
+ DWORD AddressOfData;
+ } u1;
+
+} IMAGE_THUNK_DATA32, *PIMAGE_THUNK_DATA32;
+
+
+#define IMAGE_ORDINAL_FLAG32 0x80000000
+#define IMAGE_ORDINAL_FLAG64 0x8000000000000000L
+
+typedef struct _IMAGE_THUNK_DATA64 {
+ union {
+ ULONGLONG ForwarderString;
+ ULONGLONG Function;
+ ULONGLONG Ordinal;
+ ULONGLONG AddressOfData;
+ } u1;
+
+} IMAGE_THUNK_DATA64, *PIMAGE_THUNK_DATA64;
+
+
#pragma pack(pop)
diff --git a/libyara/include/yara/utils.h b/libyara/include/yara/utils.h
index 1357c36..07604d0 100644
--- a/libyara/include/yara/utils.h
+++ b/libyara/include/yara/utils.h
@@ -48,6 +48,7 @@ limitations under the License.
#ifdef WIN32
#define snprintf _snprintf
#define strcasecmp _stricmp
+#define strncasecmp _strnicmp
#endif
diff --git a/libyara/modules/pe.c b/libyara/modules/pe.c
index 4a14c97..dad4a5b 100644
--- a/libyara/modules/pe.c
+++ b/libyara/modules/pe.c
@@ -87,6 +87,23 @@ PIMAGE_NT_HEADERS32 get_pe_header(
}
+PIMAGE_DATA_DIRECTORY get_data_directory(
+ PIMAGE_NT_HEADERS32 pe_header,
+ int entry)
+{
+ PIMAGE_DATA_DIRECTORY result;
+
+ if (pe_header->FileHeader.Machine == 0x8664) // is a 64-bit PE ?
+ result = &((PIMAGE_NT_HEADERS64) pe_header)->
+ OptionalHeader.DataDirectory[entry];
+ else
+ result = &pe_header->OptionalHeader.DataDirectory[entry];
+
+ return result;
+}
+
+
+
uint64_t rva_to_offset(
PIMAGE_NT_HEADERS32 pe_header,
size_t pe_size,
@@ -265,40 +282,30 @@ define_function(section_index)
return_integer(UNDEFINED);
}
+
define_function(exports)
{
+ char* function_name = string_argument(1);
+
YR_OBJECT* self = self();
+ DATA* data = (DATA*) self->data;
PIMAGE_DATA_DIRECTORY directory;
PIMAGE_EXPORT_DIRECTORY exports;
-
DWORD* names;
- DATA* data;
- char* function_name = string_argument(1);
char* name;
-
- uint64_t offset;
int i;
-
- data = (DATA*) self->data;
+ uint64_t offset;
// if not a PE file, return UNDEFINED
if (data == NULL)
return_integer(UNDEFINED);
- if (data->pe_header->FileHeader.Machine == 0x8664) // is a 64-bit PE ?
- {
- directory = &((PIMAGE_NT_HEADERS64)
- (data->pe_header))->OptionalHeader.DataDirectory[
- IMAGE_DIRECTORY_ENTRY_EXPORT];
- }
- else
- {
- directory = &data->pe_header->OptionalHeader.DataDirectory[
- IMAGE_DIRECTORY_ENTRY_EXPORT];
- }
+ directory = get_data_directory(
+ data->pe_header,
+ IMAGE_DIRECTORY_ENTRY_EXPORT);
// if the PE doesn't export any functions, return FALSE
@@ -322,7 +329,7 @@ define_function(exports)
exports->AddressOfNames);
if (offset == 0 ||
- offset >= data->size - exports->NumberOfNames * sizeof(DWORD))
+ offset + exports->NumberOfNames * sizeof(DWORD) > data->size)
return_integer(0);
names = (DWORD*)(data->data + offset);
@@ -347,6 +354,125 @@ define_function(exports)
}
+define_function(imports)
+{
+ char* dll_name = string_argument(1);
+ char* function_name = string_argument(2);
+
+ YR_OBJECT* self = self();
+ DATA* data = (DATA*) self->data;
+
+ PIMAGE_DATA_DIRECTORY directory;
+ PIMAGE_IMPORT_DESCRIPTOR imports;
+ PIMAGE_IMPORT_BY_NAME import;
+ PIMAGE_THUNK_DATA32 thunks32;
+ PIMAGE_THUNK_DATA64 thunks64;
+
+ uint8_t* data_end;
+ uint64_t offset;
+
+ // if not a PE file, return UNDEFINED
+
+ if (data == NULL)
+ return_integer(UNDEFINED);
+
+ data_end = data->data + data->size;
+
+ directory = get_data_directory(
+ data->pe_header,
+ IMAGE_DIRECTORY_ENTRY_IMPORT);
+
+ if (directory->VirtualAddress == 0)
+ return_integer(0);
+
+ offset = rva_to_offset(
+ data->pe_header,
+ data->pe_size,
+ directory->VirtualAddress);
+
+ if (offset == 0 ||
+ offset + sizeof(IMAGE_IMPORT_DESCRIPTOR) > data->size)
+ return_integer(0);
+
+ imports = (PIMAGE_IMPORT_DESCRIPTOR)(data->data + offset);
+
+ while (imports->Name != 0)
+ {
+ offset = rva_to_offset(
+ data->pe_header,
+ data->pe_size,
+ imports->Name);
+
+ if (offset != 0 &&
+ offset <= data->size &&
+ strncasecmp(
+ dll_name,
+ (char*)(data->data + offset),
+ data->size - offset) == 0)
+ {
+ offset = rva_to_offset(
+ data->pe_header,
+ data->pe_size,
+ imports->OriginalFirstThunk);
+
+ if (data->pe_header->FileHeader.Machine == 0x8664)
+ {
+ thunks64 = (PIMAGE_THUNK_DATA64)(data->data + offset);
+
+ while (thunks64->u1.Ordinal != 0)
+ {
+ if (!(thunks64->u1.Ordinal & IMAGE_ORDINAL_FLAG64))
+ {
+ // if not exported by ordinal
+ offset = rva_to_offset(
+ data->pe_header,
+ data->pe_size,
+ thunks64->u1.Function);
+
+ import = (PIMAGE_IMPORT_BY_NAME)(data->data + offset);
+
+ if (strcmp((char*) import->Name, function_name) == 0)
+ return_integer(1);
+ }
+
+ thunks64++;
+ }
+ }
+ else
+ {
+ thunks32 = (PIMAGE_THUNK_DATA32)(data->data + offset);
+
+ while (thunks32->u1.Ordinal != 0)
+ {
+ if (!(thunks32->u1.Ordinal & IMAGE_ORDINAL_FLAG32))
+ {
+ // if not exported by ordinal
+ offset = rva_to_offset(
+ data->pe_header,
+ data->pe_size,
+ thunks32->u1.Function);
+
+ import = (PIMAGE_IMPORT_BY_NAME)(data->data + offset);
+
+ if (strcmp((char*) import->Name, function_name) == 0)
+ return_integer(1);
+ }
+
+ thunks32++;
+ }
+ }
+ }
+
+ imports++;
+
+ if ((uint8_t*) imports > data_end - sizeof(IMAGE_IMPORT_DESCRIPTOR))
+ break;
+ }
+
+ return_integer(0);
+}
+
+
begin_declarations;
integer("MACHINE_I386");
@@ -416,8 +542,9 @@ begin_declarations;
end_struct_array("sections");
function("section_index", "s", "i", section_index);
-
function("exports", "s", "i", exports);
+ function("imports", "ss", "i", imports);
+
end_declarations;
@@ -435,32 +562,56 @@ int module_load(
size_t pe_size;
- set_integer(IMAGE_FILE_MACHINE_I386, module, "MACHINE_I386");
- set_integer(IMAGE_FILE_MACHINE_AMD64, module, "MACHINE_AMD64");
-
- set_integer(IMAGE_SUBSYSTEM_UNKNOWN, module, "SUBSYSTEM_UNKNOWN");
- set_integer(IMAGE_SUBSYSTEM_NATIVE, module, "SUBSYSTEM_NATIVE");
- set_integer(IMAGE_SUBSYSTEM_WINDOWS_GUI, module, "SUBSYSTEM_WINDOWS_GUI");
- set_integer(IMAGE_SUBSYSTEM_WINDOWS_CUI, module, "SUBSYSTEM_WINDOWS_CUI");
- set_integer(IMAGE_SUBSYSTEM_OS2_CUI, module, "SUBSYSTEM_OS2_CUI");
- set_integer(IMAGE_SUBSYSTEM_POSIX_CUI, module, "SUBSYSTEM_POSIX_CUI");
- set_integer(IMAGE_SUBSYSTEM_NATIVE_WINDOWS, module, "SUBSYSTEM_NATIVE_WINDOWS");
-
- set_integer(IMAGE_FILE_RELOCS_STRIPPED, module, "RELOCS_STRIPPED");
- set_integer(IMAGE_FILE_EXECUTABLE_IMAGE, module, "EXECUTABLE_IMAGE");
- set_integer(IMAGE_FILE_LINE_NUMS_STRIPPED, module, "LINE_NUMS_STRIPPED");
- set_integer(IMAGE_FILE_LOCAL_SYMS_STRIPPED, module, "LOCAL_SYMS_STRIPPED");
- set_integer(IMAGE_FILE_AGGRESIVE_WS_TRIM, module, "AGGRESIVE_WS_TRIM");
- set_integer(IMAGE_FILE_LARGE_ADDRESS_AWARE, module, "LARGE_ADDRESS_AWARE");
- set_integer(IMAGE_FILE_BYTES_REVERSED_LO, module, "BYTES_REVERSED_LO");
- set_integer(IMAGE_FILE_32BIT_MACHINE, module, "32BIT_MACHINE");
- set_integer(IMAGE_FILE_DEBUG_STRIPPED, module, "DEBUG_STRIPPED");
- set_integer(IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP, module, "REMOVABLE_RUN_FROM_SWAP");
- set_integer(IMAGE_FILE_NET_RUN_FROM_SWAP, module, "NET_RUN_FROM_SWAP");
- set_integer(IMAGE_FILE_SYSTEM, module, "SYSTEM");
- set_integer(IMAGE_FILE_DLL, module, "DLL");
- set_integer(IMAGE_FILE_UP_SYSTEM_ONLY, module, "UP_SYSTEM_ONLY");
- set_integer(IMAGE_FILE_BYTES_REVERSED_HI, module, "BYTES_REVERSED_HI");
+ set_integer(
+ IMAGE_FILE_MACHINE_I386, module, "MACHINE_I386");
+ set_integer(
+ IMAGE_FILE_MACHINE_AMD64, module, "MACHINE_AMD64");
+
+ set_integer(
+ IMAGE_SUBSYSTEM_UNKNOWN, module, "SUBSYSTEM_UNKNOWN");
+ set_integer(
+ IMAGE_SUBSYSTEM_NATIVE, module, "SUBSYSTEM_NATIVE");
+ set_integer(
+ IMAGE_SUBSYSTEM_WINDOWS_GUI, module, "SUBSYSTEM_WINDOWS_GUI");
+ set_integer(
+ IMAGE_SUBSYSTEM_WINDOWS_CUI, module, "SUBSYSTEM_WINDOWS_CUI");
+ set_integer(
+ IMAGE_SUBSYSTEM_OS2_CUI, module, "SUBSYSTEM_OS2_CUI");
+ set_integer(
+ IMAGE_SUBSYSTEM_POSIX_CUI, module, "SUBSYSTEM_POSIX_CUI");
+ set_integer(
+ IMAGE_SUBSYSTEM_NATIVE_WINDOWS, module, "SUBSYSTEM_NATIVE_WINDOWS");
+
+ set_integer(
+ IMAGE_FILE_RELOCS_STRIPPED, module, "RELOCS_STRIPPED");
+ set_integer(
+ IMAGE_FILE_EXECUTABLE_IMAGE, module, "EXECUTABLE_IMAGE");
+ set_integer(
+ IMAGE_FILE_LINE_NUMS_STRIPPED, module, "LINE_NUMS_STRIPPED");
+ set_integer(
+ IMAGE_FILE_LOCAL_SYMS_STRIPPED, module, "LOCAL_SYMS_STRIPPED");
+ set_integer(
+ IMAGE_FILE_AGGRESIVE_WS_TRIM, module, "AGGRESIVE_WS_TRIM");
+ set_integer(
+ IMAGE_FILE_LARGE_ADDRESS_AWARE, module, "LARGE_ADDRESS_AWARE");
+ set_integer(
+ IMAGE_FILE_BYTES_REVERSED_LO, module, "BYTES_REVERSED_LO");
+ set_integer(
+ IMAGE_FILE_32BIT_MACHINE, module, "32BIT_MACHINE");
+ set_integer(
+ IMAGE_FILE_DEBUG_STRIPPED, module, "DEBUG_STRIPPED");
+ set_integer(
+ IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP, module, "REMOVABLE_RUN_FROM_SWAP");
+ set_integer(
+ IMAGE_FILE_NET_RUN_FROM_SWAP, module, "NET_RUN_FROM_SWAP");
+ set_integer(
+ IMAGE_FILE_SYSTEM, module, "SYSTEM");
+ set_integer(
+ IMAGE_FILE_DLL, module, "DLL");
+ set_integer(
+ IMAGE_FILE_UP_SYSTEM_ONLY, module, "UP_SYSTEM_ONLY");
+ set_integer(
+ IMAGE_FILE_BYTES_REVERSED_HI, module, "BYTES_REVERSED_HI");
foreach_memory_block(context, block)
{
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/forensics/yara.git
More information about the forensics-changes
mailing list