[Forensics-changes] [yara] 44/192: pe: Add checksum field, function to calculate the checksum (#528)

Hilko Bengen bengen at moszumanska.debian.org
Sat Jul 1 10:31:44 UTC 2017


This is an automated email from the git hooks/post-receive script.

bengen pushed a commit to annotated tag v3.6.0
in repository yara.

commit e43ca52f434ef7698aee99dcf8ab7a6756c3214b
Author: Hilko Bengen <hillu at users.noreply.github.com>
Date:   Fri Sep 23 17:31:05 2016 +0200

    pe: Add checksum field, function to calculate the checksum (#528)
    
    * Add pe.checksum field
    
    * Add pe.calculate_checksum function
    
    * Add documentation for pe.checksum, pe.calculate_checksum
    
    * Add tests for pe.checksum, pe.calculate_checksum
---
 docs/modules/pe.rst  | 14 ++++++++++++++
 libyara/modules/pe.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 tests/test-pe.c      |  9 +++++++++
 3 files changed, 71 insertions(+)

diff --git a/docs/modules/pe.rst b/docs/modules/pe.rst
index dae2229..bf8a747 100644
--- a/docs/modules/pe.rst
+++ b/docs/modules/pe.rst
@@ -64,6 +64,20 @@ Reference
 
     *Example: pe.machine == pe.MACHINE_AMD64*
 
+.. c:type:: checksum
+
+    .. versionadded:: 3.6.0
+
+    Integer with the "PE checksum" as stored in the OptionalHeader
+
+.. c:type:: calculate_checksum
+
+    .. versionadded:: 3.6.0
+
+    Function that calculates the "PE checksum"
+
+    *Example: pe.checksum == pe.calculate_checksum()*
+
 .. c:type:: subsystem
 
     Integer with one of the following values:
diff --git a/libyara/modules/pe.c b/libyara/modules/pe.c
index d2bd381..4908ba1 100644
--- a/libyara/modules/pe.c
+++ b/libyara/modules/pe.c
@@ -1223,6 +1223,10 @@ void pe_parse_header(
       pe->object, "subsystem_version.minor");
 
   set_integer(
+      OptionalHeader(pe, CheckSum),
+      pe->object, "checksum");
+
+  set_integer(
       OptionalHeader(pe, Subsystem),
       pe->object, "subsystem");
 
@@ -1849,6 +1853,48 @@ define_function(rich_toolid_version)
       rich_internal(module(), integer_argument(2), integer_argument(1)));
 }
 
+
+define_function(calculate_checksum)
+{
+  uint64_t csum = 0;
+
+  YR_OBJECT* module = module();
+  PE* pe = (PE*) module->data;
+  if (pe == NULL)
+    return_integer(UNDEFINED);
+
+  int csum_offset = ((uint8_t*)&(pe->header->OptionalHeader) +
+		     offsetof(IMAGE_OPTIONAL_HEADER32, CheckSum)) - pe->data;
+  for (int i = 0; i <= pe->data_size / 4; i++)
+  {
+    // Treat the CheckSum field as 0 -- the offset is the same for
+    // PE32 and PE64.
+    if (4 * i == csum_offset)
+      continue;
+    if (4 * i+4 < pe->data_size)
+    {
+      csum += ((uint64_t) pe->data[4 * i] +
+	       ((uint64_t) pe->data[4 * i + 1] << 8)  +
+	       ((uint64_t) pe->data[4 * i + 2] << 16) +
+	       ((uint64_t) pe->data[4 * i + 3] << 24));
+    }
+    else
+    {
+      for (int j = 0; j < pe->data_size % 4; j++)
+	csum += (uint64_t) pe->data[4 * i + j] << (8 * j);
+    }
+    if (csum > 0xffffffff)
+      csum = (csum & 0xffffffff) + (csum >> 32);
+  }
+  csum = (csum & 0xffff) + (csum >> 16);
+  csum += (csum >> 16);
+  csum &= 0xffff;
+  csum += pe->data_size;
+
+  return_integer(csum);
+}
+
+
 begin_declarations;
 
   declare_integer("MACHINE_UNKNOWN");
@@ -1964,6 +2010,8 @@ begin_declarations;
     declare_integer("minor");
   end_struct("subsystem_version");
 
+  declare_integer("checksum");
+  declare_function("calculate_checksum", "", "i", calculate_checksum);
   declare_integer("subsystem");
 
   begin_struct_array("sections");
diff --git a/tests/test-pe.c b/tests/test-pe.c
index c2c6270..d90c8fa 100644
--- a/tests/test-pe.c
+++ b/tests/test-pe.c
@@ -14,6 +14,15 @@ int main(int argc, char** argv)
   assert_false_rule_file("import \"pe\" rule test { condition: pe.imports(\"KERNEL32.dll\", \"DeleteCriticalSection\") }",
       "tests/data/tiny-idata-5200");
 
+  assert_true_rule_file("import \"pe\" rule test { condition: pe.checksum == 0xA8DC }",
+      "tests/data/tiny");
+
+  assert_true_rule_file("import \"pe\" rule test { condition: pe.checksum == pe.calculate_checksum() }",
+      "tests/data/tiny");
+
+  assert_false_rule_file("import \"pe\" rule test { condition: pe.checksum == pe.calculate_checksum() }",
+      "tests/data/tiny-idata-51ff");
+
   yr_finalize();
   return 0;
 }

-- 
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