46 Commits
Author SHA1 Message Date
jmestwa-coder 605452e580 check stored digest length before comparing authenticode digests (#2234)
the digest carried in a signature can be shorter than the digest algorithm's output size, so the memcmp in parse_authenticode and pkcs9_countersig_new reads past the stored digest; compare the lengths first, the way countersignature.c already does at its other three digest compares.
2026-07-28 12:59:52 +02:00
jmestwa-coder 1d58245c8e read dotnet and pe file fields through unaligned helpers (#2210) 2026-06-24 11:49:17 +02:00
jmestwa-coder 690b3d0fda guard against undersized rich header in pe_parse_rich_signature (#2200)
When the backward scan in pe_parse_rich_signature finds a DanS marker only one to three dwords ahead of the Rich marker, rich_len ends up smaller than RICH_SIGNATURE. The unsigned subtraction rich_len - sizeof(RICH_SIGNATURE) then wraps and rich_count becomes a huge bogus value that drives the version_data allocation and copy loop. _rich_version already rejects rich_length < sizeof(RICH_SIGNATURE) for the same computation, so apply the same check before computing rich_count here.
2026-06-01 12:34:37 +02:00
Victor M. Alvarez 01032a6cb2 Fix bug while calculating the imphash in PE files.
When the file imported DLLs that contained a dot (.) in its name, like `glib-2.0.dll`, the file extension was not properly removed, causing the the imphash to be wrong.
2023-11-17 11:37:35 +01:00
Victor M. Alvarez 7def444cb9 Improve extraction of PDB path from PE files.
A check in `pe_parse_debug_directory` was verifying that the size of the debug directory entry was a multiple of `sizeof(IMAGE_DEBUG_DIRECTORY)`. Although this is true in most cases, is not universally true for all PE files. This check was preventing the extraction of the PDB path from certain EFI boot files, like the ones below. The PDB path in such cases is not a file path but a GUID, though.

Some affected files:

`6c2abf4b80a87e63eee2996e5cea8f004d49ec0c1806080fa72e960529cba14c`
`5487a2ff41e360b1d3b0a58e393b0041c3f269f1053a3e367dfecd48e233457e`
2023-11-09 09:31:47 +01:00
John 52e4f1c8f3 Revert "LNK Module (#1957)"
This reverts commit 8ce0c6c4eb. See comments in https://github.com/VirusTotal/yara/pull/1957 for more context.
2023-10-06 11:01:02 +02:00
John 8ce0c6c4eb LNK Module (#1957)
* LNK module initial commit

* Update atom logic to properly score [A-Z]

The documentation says `Bytes [a-zA-Z] contribute 18 points each`, but it looks like in the code that only `[a-z]` is given 18 points, whereas `[A-Z]` is given 20 points. This commit will make sure these ranges have the proper scoring as expected.

* Add test for comparing atom quality ABCD == abcd

Add test entry which compares the atom quality of "ABCD" and "abcd" and asserts that they are equal.

* Update test-atoms.c

* Revert "Update atom logic to properly score [A-Z]"

This reverts commit bf7130ff0b.

* Revert "Add test for comparing atom quality ABCD == abcd"

This reverts commit 181dbf2326.

* Revert "Update test-atoms.c"

This reverts commit 81239034b3.

* Test

* Revert "Test"

This reverts commit 1c53212b63.

* Add objects for LinkFlags parsing

Also fixed `DWORD` compiling error, and replaced with `uint32_t` types.

* Add file attribute flags

* Start hotkey parsing code

* Add the rest of the hotkey values

* Add initial test case for LNK module

Using the sample LNK from the MS standard for LNK files for testing, and putting in an initial test:
https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-SHLLINK/%5bMS-SHLLINK%5d.pdf

* Add initial LNK tests

* Add has_hotkey variable

* Formatting

* Fix timestamps set

Previous version always seemed to be an hour (3600 seconds) off what it should have been. This commit adds a test to make sure it's getting the right value.

I don't know why its always an hour off, but this should fix it!

* Refactor hotkey char select into its own function

* Add a couple of comments

* Add min size for parsing LNK

All the mandatory LNK header bytes add up to 76 bytes, and as such we won't parse an LNK file unless it is at least 76 bytes in length

* Add LinkTargetIDList parsing

* Begin working on code for LinkInfo parsing

* Refactor code into header + util files

Moving a lot of the definitions over to a separate header file to keep the main code clean.

Also following the PE module's structure of having a separate `lnk_utils` file to deal with some of the convenient functions it provides.

* Starting VolumeID parsing

* Adding free statement

* Add some VolumeID tests and fix free error

* Finish parsing VolumeID

* Parse LocalBasePath

* Refactor to prevent unsafe memory copying

Start taking into account the remaining size in the block being scanned, to make sure we don't break anything when dereferencing pointers.

* Parse CommonPathSuffix

Also create empty function for when we need to parse CommonNetworkRelativeLink

* Parse LocalBasePathUnicode and CommonPathSuffixUnicode

NOTE: these will need some testing before this will be production ready, as I'm making a lot of assumptions here.

* Return size of LinkInfo section

* Add StringData parsing

* Add initial code for parsing ExtraData section

Only parsing `TrackerDataBlock` at the moment, but setting up values in advance of setting up the other structures/parsers

* Add the remaining ExtraData structures

In some cases I don't make a structure where the parsing function will just handle the data (e.g. where there is variable data).

I will likely also ignore PropertyStore for now as that has separate documentation to parse it.

* More specific parsing of Droid GUIDs

* Move code out of VolumeID parsing indent

The rest of the LinkInfo section wasn't parsing unless a VolumeID was present, which shouldn't be how it works.

* Remove incorrect CommonNetworkRelativeLinkOffset setting

Also add structure for CommonNetworkRelativeLink parsing

* Implement CommonNetworkRelativeLink parsing

And add a couple of test cases for it

* Formatting

* Make LinkInfo parsing memory safe

* Remove unnecessary constant

* Make StringData parsing memory safe

Also convert `block_data_size_remaining` to `int` from `size_t`. This is because we don't want to underflow the `size_t` type, and assume we have more data left than we actually do.

* Fix up block data size remaining calculations in ExtraData

* Add more constants

* Add in overlay variable

* Make current ExtraData function memory safe

* Setup switch/case for ExtraData parsing

* ConsoleDataBlock parsing

* Add ConsoleFedData parsing

* Convert tracker data to struct and add more fields

* Add extra fields to current ExtraData structures

* Refactor structures

* Rename sample LNKs

* Refactor into parse_volume_id

* Parse DarwinData and fixed up block struct entries

* Add is_malformed entry

Checks whether a LNK has failed parsing due to it being malformed.

* Add overlay test case

* Parse EnvironmentVariableDataBlock

* Parse IconEnvironmentDataBlock

* Add KnownFolderDataBlock parsing

* Add placeholder parsing for PropertyDataStoreBlock

* Parse ShimDataBlock

* Parse SpecialFolderDataBlock

* Remove id_list_ptr var

* Refactor into its own function to parse IDList

* Parse VistaAndAboveIDListDataBlock

* Remove printf

* Refactor item_id_list into structure

* Add LinkInfoFlags as external variables

* Only process relevant link info if flags set

* Update StringData to also accept ASCII

I assumed it would only be ASCII, but the `IsUnicode` flag can help indicate what type of string it is.

* Only parse ExtraData if there is data left

* Retype to strings

* Fix environment var data parsing

I thought wchar_t was 16 bits, but turns out it can also be 32 bits... I'll need to change up other routines to take this into account as well

* Move inside if statement to prevent setting

* Fix icon env unicode issue

* Convert remaining wchar_t struct entries

* Add ExtraData test cases

* Add ExtraData tests (2)

* Make sure timestamps are UTC

* Start LNK module documentation

* Add ShowCommand constants

* Finish documenting LNK headers

* Change test to flag comparison

* Correct structure names

* Update test-lnk.c

* Document LinkInfo section

* Document StringData

* Add more constants

* Document ConsoleData

* Update lnk.rst

* Finish documenting LNK module

* Some extra comments

* Update lnk.rst

* Apply clang formatting

* Removed test for now

* Add more flags and renamed console_fe_data

* Formatting

* Update comment on PropertyStoreData

* Change variable names due to potential clashes

Changed the variables used in header files:
- Reserved1
- Reserved2
- Unused1
- Unused2

The CI/CD seems to fail with these values as a default, so I'm hoping changing them fixes things

* Change packing to address misaligned pointer error

* Add LNK module to VS Projects

* Changed `block_data_size_remaining` to `unsigned int`

Make variable `unsigned int` instead of just `int` to prevent the value being negative.

* Begin removing static of strings

Starting with the ones I can test, by dynamically allocating memory after doing the check, I'm removing the possibility of there being a buffer overflow on this data.

* Dynamically allocate `volume_id_data`

* Remove more statically typed char arrays

* Dynamically allocate unicode strings

Previously were statically set in length, now dynamically allocated

* Add clearer comment

* Add todo

* Add `yr_` prefix to necessary functions

Due to #1762, needed to add `yr_` as a prefix to functions like `set_string`

* Convert 'unsigned int' to `uint32_t`

* Make constants have consistent casing

* Add extra checks on block size remaining

I found a case where a function returned a section size that was greater than the remaining block size, which caused a crash. This patch checks each value returned to make sure the next stage doesn't fail to parse.

* Fix docs for icon_location

Add `lnk.` prefix to `icon_location` variable

* Add LNK module back in

* Correct LNK module source path

* Add lnk_utils to modules list

And update other libyara auto changes

* Add LNK module tests

* Fix up LNK test in Makefile

* Fix typo in test LNK

* Attempt to fix bazel build

* Testing to see why Bazel build fails

* Revert removing tests

It seems even one test gives the error `There were tests whose specified size is too big. Use the --test_verbose_timeout_warnings command line option to see which ones these are.`

* Include LNK module in BUILD.bazel

* Add missing deps line

* Add lnk.h to Makefile

* Add lnk.h to yara.bzl

* Add lnk_utils.h to yara.bzl

* Revert automatic changes

Change some C/header files that got automatically changed while compiling YARA to the same that they are on the main branch

* Include lnk_utils in Makefile

* Convert some console data variables to signed and update docs

Some variables in the console data section are actually signed variables. So I've converted them to `int16_t` instead of `uint16_t`, added some test cases to make sure these values are properly parsed, and added some examples in the docs.

* Fix typo for window_size_y

* Add flags for LNK module

* Add extra time tests

Add tests for access time and write time

* Temporary update for debugging

Attempting to update this temporarily in order to test big endian issues on this branch - revert before merging

* Revert "Temporary update for debugging"

This reverts commit 2120c7e2e5.

* Temporary change for debugging

* Change order

* Temporarily disable most tests

* Initial big endian test fix

* LNK header endian fix

* Update test-lnk.c

* Fix up time conversion function calls

* Re-enable item ID tests

* Focus on item_id_list_size test

* Fix endianness of parse_link_target_id_list

* Fix endianness of parse_id_list

* Fix endianness of link_info

* Finish applying endianness fixes

Enabled all tests now

* Roll back to test console data and string data

* Add missing endianness conversion

* Re-enable all tests

* Revert back to original state
2023-08-25 09:05:48 +02:00
John c41906bb13 Revert "LNK module (#1732)"
This reverts commit 97fd691086.
2023-08-24 09:55:14 +02:00
John 97fd691086 LNK module (#1732)
* LNK module initial commit

* Update atom logic to properly score [A-Z]

The documentation says `Bytes [a-zA-Z] contribute 18 points each`, but it looks like in the code that only `[a-z]` is given 18 points, whereas `[A-Z]` is given 20 points. This commit will make sure these ranges have the proper scoring as expected.

* Add test for comparing atom quality ABCD == abcd

Add test entry which compares the atom quality of "ABCD" and "abcd" and asserts that they are equal.

* Update test-atoms.c

* Revert "Update atom logic to properly score [A-Z]"

This reverts commit bf7130ff0b.

* Revert "Add test for comparing atom quality ABCD == abcd"

This reverts commit 181dbf2326.

* Revert "Update test-atoms.c"

This reverts commit 81239034b3.

* Test

* Revert "Test"

This reverts commit 1c53212b63.

* Add objects for LinkFlags parsing

Also fixed `DWORD` compiling error, and replaced with `uint32_t` types.

* Add file attribute flags

* Start hotkey parsing code

* Add the rest of the hotkey values

* Add initial test case for LNK module

Using the sample LNK from the MS standard for LNK files for testing, and putting in an initial test:
https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-SHLLINK/%5bMS-SHLLINK%5d.pdf

* Add initial LNK tests

* Add has_hotkey variable

* Formatting

* Fix timestamps set

Previous version always seemed to be an hour (3600 seconds) off what it should have been. This commit adds a test to make sure it's getting the right value.

I don't know why its always an hour off, but this should fix it!

* Refactor hotkey char select into its own function

* Add a couple of comments

* Add min size for parsing LNK

All the mandatory LNK header bytes add up to 76 bytes, and as such we won't parse an LNK file unless it is at least 76 bytes in length

* Add LinkTargetIDList parsing

* Begin working on code for LinkInfo parsing

* Refactor code into header + util files

Moving a lot of the definitions over to a separate header file to keep the main code clean.

Also following the PE module's structure of having a separate `lnk_utils` file to deal with some of the convenient functions it provides.

* Starting VolumeID parsing

* Adding free statement

* Add some VolumeID tests and fix free error

* Finish parsing VolumeID

* Parse LocalBasePath

* Refactor to prevent unsafe memory copying

Start taking into account the remaining size in the block being scanned, to make sure we don't break anything when dereferencing pointers.

* Parse CommonPathSuffix

Also create empty function for when we need to parse CommonNetworkRelativeLink

* Parse LocalBasePathUnicode and CommonPathSuffixUnicode

NOTE: these will need some testing before this will be production ready, as I'm making a lot of assumptions here.

* Return size of LinkInfo section

* Add StringData parsing

* Add initial code for parsing ExtraData section

Only parsing `TrackerDataBlock` at the moment, but setting up values in advance of setting up the other structures/parsers

* Add the remaining ExtraData structures

In some cases I don't make a structure where the parsing function will just handle the data (e.g. where there is variable data).

I will likely also ignore PropertyStore for now as that has separate documentation to parse it.

* More specific parsing of Droid GUIDs

* Move code out of VolumeID parsing indent

The rest of the LinkInfo section wasn't parsing unless a VolumeID was present, which shouldn't be how it works.

* Remove incorrect CommonNetworkRelativeLinkOffset setting

Also add structure for CommonNetworkRelativeLink parsing

* Implement CommonNetworkRelativeLink parsing

And add a couple of test cases for it

* Formatting

* Make LinkInfo parsing memory safe

* Remove unnecessary constant

* Make StringData parsing memory safe

Also convert `block_data_size_remaining` to `int` from `size_t`. This is because we don't want to underflow the `size_t` type, and assume we have more data left than we actually do.

* Fix up block data size remaining calculations in ExtraData

* Add more constants

* Add in overlay variable

* Make current ExtraData function memory safe

* Setup switch/case for ExtraData parsing

* ConsoleDataBlock parsing

* Add ConsoleFedData parsing

* Convert tracker data to struct and add more fields

* Add extra fields to current ExtraData structures

* Refactor structures

* Rename sample LNKs

* Refactor into parse_volume_id

* Parse DarwinData and fixed up block struct entries

* Add is_malformed entry

Checks whether a LNK has failed parsing due to it being malformed.

* Add overlay test case

* Parse EnvironmentVariableDataBlock

* Parse IconEnvironmentDataBlock

* Add KnownFolderDataBlock parsing

* Add placeholder parsing for PropertyDataStoreBlock

* Parse ShimDataBlock

* Parse SpecialFolderDataBlock

* Remove id_list_ptr var

* Refactor into its own function to parse IDList

* Parse VistaAndAboveIDListDataBlock

* Remove printf

* Refactor item_id_list into structure

* Add LinkInfoFlags as external variables

* Only process relevant link info if flags set

* Update StringData to also accept ASCII

I assumed it would only be ASCII, but the `IsUnicode` flag can help indicate what type of string it is.

* Only parse ExtraData if there is data left

* Retype to strings

* Fix environment var data parsing

I thought wchar_t was 16 bits, but turns out it can also be 32 bits... I'll need to change up other routines to take this into account as well

* Move inside if statement to prevent setting

* Fix icon env unicode issue

* Convert remaining wchar_t struct entries

* Add ExtraData test cases

* Add ExtraData tests (2)

* Make sure timestamps are UTC

* Start LNK module documentation

* Add ShowCommand constants

* Finish documenting LNK headers

* Change test to flag comparison

* Correct structure names

* Update test-lnk.c

* Document LinkInfo section

* Document StringData

* Add more constants

* Document ConsoleData

* Update lnk.rst

* Finish documenting LNK module

* Some extra comments

* Update lnk.rst

* Apply clang formatting

* Removed test for now

* Add more flags and renamed console_fe_data

* Formatting

* Update comment on PropertyStoreData

* Change variable names due to potential clashes

Changed the variables used in header files:
- Reserved1
- Reserved2
- Unused1
- Unused2

The CI/CD seems to fail with these values as a default, so I'm hoping changing them fixes things

* Change packing to address misaligned pointer error

* Add LNK module to VS Projects

* Changed `block_data_size_remaining` to `unsigned int`

Make variable `unsigned int` instead of just `int` to prevent the value being negative.

* Begin removing static of strings

Starting with the ones I can test, by dynamically allocating memory after doing the check, I'm removing the possibility of there being a buffer overflow on this data.

* Dynamically allocate `volume_id_data`

* Remove more statically typed char arrays

* Dynamically allocate unicode strings

Previously were statically set in length, now dynamically allocated

* Add clearer comment

* Add todo

* Add `yr_` prefix to necessary functions

Due to #1762, needed to add `yr_` as a prefix to functions like `set_string`

* Convert 'unsigned int' to `uint32_t`

* Make constants have consistent casing

* Add extra checks on block size remaining

I found a case where a function returned a section size that was greater than the remaining block size, which caused a crash. This patch checks each value returned to make sure the next stage doesn't fail to parse.

* Fix docs for icon_location

Add `lnk.` prefix to `icon_location` variable

* Add LNK module back in

* Correct LNK module source path

* Add lnk_utils to modules list

And update other libyara auto changes

* Add LNK module tests

* Fix up LNK test in Makefile

* Fix typo in test LNK

* Attempt to fix bazel build

* Testing to see why Bazel build fails

* Revert removing tests

It seems even one test gives the error `There were tests whose specified size is too big. Use the --test_verbose_timeout_warnings command line option to see which ones these are.`

* Include LNK module in BUILD.bazel

* Add missing deps line

* Add lnk.h to Makefile

* Add lnk.h to yara.bzl

* Add lnk_utils.h to yara.bzl

* Revert automatic changes

Change some C/header files that got automatically changed while compiling YARA to the same that they are on the main branch

* Include lnk_utils in Makefile

* Convert some console data variables to signed and update docs

Some variables in the console data section are actually signed variables. So I've converted them to `int16_t` instead of `uint16_t`, added some test cases to make sure these values are properly parsed, and added some examples in the docs.

* Fix typo for window_size_y

* Add flags for LNK module

* Add extra time tests

Add tests for access time and write time
2023-08-24 09:32:54 +02:00
Wesley Shields e94ec7b621 Fix imphash issue with empty import names. (#1944)
* Fix imphash issue with empty import names.

If an import has an empty name skip processing it. This is consistent with the
behavior of pefile (https://github.com/erocarrera/pefile/blob/593d094e35198dad92aaf040bef17eb800c8a373/pefile.py#L5871-L5872).

Add a test case which is just the tiny test file with the first import name set
to all NULL bytes. I tested that pefile calculates the imphash of it, which
matches what YARA now calculates too:

>>> import pefile
>>> pe = pefile.PE('/Users/wxs/src/yara/tests/data/tiny_empty_import_name')
>>> pe.get_imphash()
'0eff3a0eb037af8c1ef0bada984d6af5'
>>>

Fixes #1943

* Add test file forgot in last commit.

* Handle invalid import names.

If an imported function does not contain ONLY a-zA-Z0-9 and a small subset of
special characters it will now be ignored.  This aligns us better with pefile,
which checks for valid import names and skips them if they are invalid.

I've also updated the test file to check that these special characters are
handled properly.

* Fix test after alignment with pefile.

Turns out that the tiny-idata-5200 file is corrupted to the point that pefile
doesn't parse it. For example, it finds no imports to hash:

```
>>> pe = pefile.PE('tests/data/tiny-idata-5200')
>>> pe.get_imphash()
''
>>>
```

We were parsing imports from this file before these changes that were incorrect,
so fix the tests to reflect the fact that we parse no imports from this file
anymore.

As part of this I've split the checks for number of parsed imports and
successfully parsed imports into two different counters, which now means we are
accurately reflecting when we are able to parse the import table but not the
descriptors in it while still making sure we don't parse too many as we have
seen before.

* Move declarations to align better.

Move these declaractions so they are with the rest of the constants. This makes
the output of -D easier to read.

* Fix memory leak when handling corrupt imports.

If we have an invalid import name we need to free the name and continue to the
next thunk and function. While fixing this I noticed that if we fail to alloc an
IMPORT_FUNCTION* we would end up looping endlessly because we were never
incrementing the thunk pointer or function index. Fix it by ALWAYS incrementing
those at the end of the loop and conditionally populating the newly allocated
node.
2023-08-18 13:25:44 +02:00
Tomáš Ďuriš 148dac6788 Return YR_UNDEFINED when offset is not valid (#1881) 2023-03-22 09:50:15 +01:00
Vincent Thiberville 26cca748c1 fix telfhash computation on x64 specific functions (#1847)
The telfhash algorithm excludes x64 functions, see here:
https://github.com/trendmicro/telfhash/blob/d2a82f85a5b/telfhash/telfhash.py#L59

Looks like there was a copy paste error when porting this algorithm in
YARA, as the test for "is_bad_prefix" is copied, but this is not the
right test of "is_x86_64".

This PR properly fixes it.
2023-01-10 09:50:00 +01:00
Wesley ShieldsandPeter Babka 0a2d31f281 Collect some open PRs for inclusion for 4.3.0 (#1835)
* Fix `pe_rva_to_offset`

* Fix: checking if RVA is inside section
* Fix: real pointer to raw data is aligned down to sector size

* Add pe.import_rva() functions.

Add pe.import_rva("foo.dll", "func1") which returns the RVA of the imported
function. Also add pe.import_rva("foo.dll", 1) which does the same but the
import is done by ordinal.

* Implement delayed import RVA and add docs.

* Add math.length()

Add a math.length() which will return the length of the sequence of bytes,
including any NULL bytes.

Fixes #1778.

* Add string module.

Move the math.to_int() functions and math.length() over to the new string
module. I decided to move the to_int() because it seems logical to convert from
a string to an integer using a string module rather than the math module.

You still use math.to_string() to convert an integer to a string, and use
string.to_int() to convert a string to an integer.

Add tests and docs for string module. Move the appropriate tests from the math
module over to the new string tests.

While here, also add the console module to the bazel build as it was apparently
missing (this is untested).

* Remove unused include.

* Add tests for https://github.com/VirusTotal/yara/pull/1561/

* Fix copyright year in string module.

Co-authored-by: Peter Babka <[email protected]>
2022-12-15 09:39:56 +01:00
HoundTheandVictor M. Alvarez 15ec337e04 Add parsing of .NET user types from .NET metadata stream (#1605)
* Add simple_str string implementation

* Add ability to parse .NET user defined types to 'dotnet' module

* Add copyright information

* Unify comment style, define iter variable within for loop

* Fix invalid handling of corrupted parameters

* Remove duplicate test_dotnet in BUILD.bazel

* Fix unaligned memory access. (#1)

* Fix unaligned memory access.

* Add missing comma in Bazel file.

Co-authored-by: Victor M. Alvarez <[email protected]>
2022-06-23 12:36:22 +02:00
dangodangodango 94a5de1903 Fix issue #1708 (#1710)
* Fix issue #1708

* Add test case for #1708

Build a dotnet pe that triggers this issue:
https://github.com/dangodangodango/BadDotnetPe
2022-05-28 22:02:21 +02:00
Victor M. AlvarezandAnton Cherepanov 2587498cbf Add support for PDB path in Apple EFI files (MTOC signature) (#1627)
Co-authored-by: Anton Cherepanov <[email protected]>
2022-01-10 17:12:39 +01:00
xbabka01 5cc28d24a2 Add parsing of '/N' section names (#1560) 2021-09-17 09:24:59 +02:00
Tomáš KenderandTomáš Kender 92005c9d40 test empty version_info value (#1548)
Co-authored-by: Tomáš Kender <[email protected]>
2021-08-25 09:47:25 +02:00
xbabka01 b8650dfa05 Add imports_details and delayed_imports_details (#1523) 2021-08-20 09:42:57 +02:00
Victor M. Alvarez e4819f6b98 Fix issue #1443. (#1445)
* Fix issue #1443.

As pointed out in the bug report the way of aligning the win_cert pointer to the next 8-bytes boundary is not correct. If the previous certificates ends at 0x1234000A, the next one should start at 0x12340010, not at 0x1234000c which is not aligned to 8 bytes.
2021-02-08 22:04:52 +01:00
Wesley Shields 95b43693dc Switch maximum string limit to warning. (#1350)
When we hit the maximum match limit on a string we currently abort all scanning,
which can be problematic since it isn't a good reason to stop all scanning, and
is better off as a warning to the user.

This commit makes it so that when the string match limit is hit a warning is
printed and scanning will continue. The warning message indicates that the
results may be invalid. It is hard to know for certain if they are invalid
because it depends entirely upon the condition. If you use the # or @ operator
then your condition _MAY_ be invalid since the total number of matches and
locations is not known anymore. Just checking that the string exists won't be an
invalid state since we have confirmed the existence of _AT LEAST_ the maximum
number of occurrences, which clearly satisfies the existence of a single
instance of your string.

I decided to implement this as a callback so the user of libyara has some choice
on the default behavior. If they want to consider this a "stop all scanning"
error they are free to return CALLBACK_ERROR in their callback.
2020-12-17 10:10:27 +01:00
Wesley Shields 0e536cbd4f Add test for invalid rsrc rva. 2020-08-22 19:07:33 +02:00
Scott Knight 793fc55358 Create test case for uninitialized number_of_segments
The current Mach-O parsing code attempts to call macho_rva_to_offset
while parsing load commands and before it has set number_of_segments.
Since macho_rva_to_offset uses number_of_segments this can result
in it using a number_of_segments that is uninitialized and is just a random
large number. In turn yara runs a really long time.

This adds a test binary based on this post

https://codegolf.stackexchange.com/questions/102471/smallest-possible-runnable-mach-o-executable/154685#154685

It has two load commands. The first is a LC_UNIXTHREAD command and
the second is a LC_SEGMENT command. It's a valid 386 Mach-O binary.
It reproduces this error.
2020-05-11 09:02:06 +02:00
Wesley Shields 2bf67e6ae8 Fix regression in export parsing.
UPX packed files will cause export parsing to stop parsing because the function
address is not a valid RVA, and I was refusing to parse that export in that
case.

This is a regression from how we used to do parsing (we were never checking the
export RVA so it was never considered in prior releases). This is causing rules
which used to work to no longer work on packed samples. Specifically, checking
for a DLL which is UPX packed using pe.exports("foo") is likely to not work in
4.0.0 when it used to work in 3.11.0.

Apologies for missing this, but to make sure it doesn't happen again in the
future I've added a test case for this (just packed an existing DLL that is in
the repo).
2020-05-01 09:45:26 +02:00
malvidin 6c1a8add6e Document and test for known base64 false positives and false negatives 2020-04-23 12:46:35 +02:00
malvidin f02a242350 Consistent use of Base64 and base64 in writingrules.rst
Add test for invalid use of base64 and fullword together
Skip second base64 encoding of single ascii byte
Add test for correct base64 encoding of single ascii byte
2020-04-23 12:46:35 +02:00
Wesley Shields 5750d7e33e Merge branch 'master' into export_addresses 2020-02-18 14:53:37 -05:00
Wesley Shields 2e755acc9e base64 and widebase64 modifiers (#1185)
Add two new modifiers: base64 and widebase64.

These modifiers take the given text string and generate 3 different strings
being careful to trim off the bytes which are dependent upon leading or
trailing bytes in the larger search space.

I've implemented it by slightly cheating. I generate all the search strings in
a list and then creating one large string suitable for the RE compiler to deal
with. For example, the string "This program cannot" generates these three
base64 encoded strings:

VGhpcyBwcm9ncmFtIGNhbm5vd
RoaXMgcHJvZ3JhbSBjYW5ub3
UaGlzIHByb2dyYW0gY2Fubm90

Those three strings are then transformed into a RE that looks like this:

(VGhpcyBwcm9ncmFtIGNhbm5vd|RoaXMgcHJvZ3JhbSBjYW5ub3|UaGlzIHByb2dyYW0gY2Fubm90)

That string is then passed to the RE compiler for parsing and AST generation.
The AST is then emitted into the appropriate spot and YARA believes it was
given a regex from that point on.

I've also implemented support for specifying custom alphabets:

base64("!@#$%^&*(){}[].,|ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstu")

This means that I have to be careful to escape any special RE characters in the
string passed to the compiler. The base64 alphabet has to be 64 bytes long, and
does support escaped bytes properly too.

To avoid the need to deal with escaping I had a first implementation which
attempted to generate the AST by hand, which was mostly working but was very
cumbersome to maintain. In doing this I ended up improving yr_re_print_node()
so that it indents the tree properly, which made debugging that attempt easier.
2020-02-17 12:27:41 +01:00
Wesley Shields 3b514fe6cd Merge branch 'master' into export_addresses 2019-11-16 17:05:28 -05:00
Wesley Shields 6d40a34260 Fix Rich header parsing. (#1164)
* Fix Rich header parsing.

The rich header doesn't always start at 0x80. The proper way to find the rich
header is to start at the NT header and work backwards one dword at a time
(technically the NT header is supposed to be 8 byte aligned, if someone has a
sample which isn't I'd love to see it) looking for Rich. Once you find it you
can get the XOR key which follows it and then continue to look backwards for
the DanS (after applying the XOR).

Decent documentation on this is at
http://bytepointer.com/articles/the_microsoft_rich_header.htm.

Also, fun fact which we may want to consider implementing is that the XOR key is
actually derived from the DOS header, so it may be an interesting way to tell if
the rich header has been tampered with if they do not properly recalculate the
key.

Fixes #1149.

* Split Rich signature walking into two loops.

While here, add a test that makes sure the clear version of the rich signature
is properly calculated.
2019-11-15 10:56:07 +01:00
Victor M. Alvarez 7a684d6de0 Fix bug in while initializing the "guids" array in "dotnet" module. (#1166)
Closes #1165
2019-11-14 19:04:18 +01:00
Victor M. Alvarez 0e52686008 Add tests for a module automatically generated from a Protocol Buffer. (#1162) 2019-11-13 17:04:24 +01:00
Wesley Shields 78241f498c Merge branch 'master' into export_addresses 2019-09-03 12:08:29 -04:00
Wesley Shields 627ef691d7 Fixes for xor modifier. (#1113)
* Fixes for xor modifier.

This commit makes the xor modifier no longer include "plaintext" versions of the
strings. In particular if you have:

$a = "This program cannot" xor

Then it will no longer match on the plaintext version of the string. It will
only match on the xor versions. If you want it to match on plaintext or xor then
you can use:

$a = "This program cannot" xor ascii

The same is true for wide.

* Make 'xor nocase' a compiler error.

* Add newline between ascii and wide strings.
2019-09-03 10:59:47 +02:00
Wesley Shields 2bafaf4ec3 Add dotnet tests. (#1109)
Add some tests for the dotnet module, which uses the smallest .NET binary I had
laying around that exercises a fair bit of the code. In particular it has a
resource, guids, assembly information and a couple of other things that make for
good tests.
2019-08-12 09:07:58 +02:00
Wesley Shields 11da16d29a Add tests and Fix incorrect return value in exports_index_regex.
Add a bunch of tests which exercise improved DLL parsing. The DLL I'm using for
testing was taken from a Windows 10 VM I had laying around and was chosen
because it was the smallest DLL I had which has at least one local function and
one forwarded function.

Also, I'm glad I wrote these tests because they exposed a copy/paste mistake in
exports_index_regex where I was returning 1 and not the index where the regex
matched.
2019-07-29 23:01:02 -04:00
Wesley Shields a43c41614c Add thumbprint to pe.signatures[] (#897)
* Add thumbprint to pe.signatures[]

* Add tests for certificate parsing.
2018-07-25 20:28:40 +02:00
Victor M. Alvarez 54059646ed Fix issue 884 (#887)
The yr_compiler_add_fd was reading only the first 1024 bytes of the file.
2018-06-01 12:33:11 +02:00
Wesley Shields 2e664c566f Implement xor modifier. (#830) 2018-02-18 19:46:08 +01:00
Victor M. Alvarez ef44bab295 Fix issue #796. 2017-11-21 19:33:57 +01:00
mbandzi 0c57f0bd66 Mach-O file format support (#617)
Add module for parsing Mach-O files.
2017-11-21 13:03:22 +01:00
Victor M. Alvarez 511e38c8ac Add data file for test case 2017-05-25 11:35:10 +02:00
Hilko Bengen c48cea7b53 Add yr_compiler_add_fd (#475)
This is a libc-neutral way to pass a file descriptor (Unix) or
HANDLE (Windows) to the rule compiler as briefly discussed in #462.
2016-09-08 19:06:21 +02:00
Victor M. Alvarez eeeb703f10 Remove files used for testing purposes that were being detected by antivirus programs. Remove .exe extension from some other files. (#512) 2016-09-06 22:20:27 +02:00
Hilko Bengen 9b141382c8 Add test case for #429
... without adding malware samples to the source tree :-)
2016-03-31 01:36:26 +02:00
Hilko Bengen 6757bcd40c tests: Add checks for #373, #399 2016-03-16 19:25:59 +01:00