Skip to content

Locate a byte signature within a buffer

Locate the first occurrence of a byte signature within a buffer, triggered when caller looks for a file-format signature (e.g. the PDF_FILE_HEADER constant "%PDF-") inside a binary payload.

Field Value
Operation ID OP-023
Trigger Caller looks for a file-format signature (e.g. the PDF_FILE_HEADER constant "%PDF-") inside a binary payload
Inputs input, searchFor (or an ASCII string), start, maxBytesToSearch
Outputs int index of the first match, or -1
Primary components `ByteExtensions.Search(this byte[] input, byte[] searchFor, int start = 0, int maxBytesToSearch = 0) and the string overload`
Entry point Common/SAIF.Common/Extensions/ByteExtensions.cs

Steps

  1. The string overload converts the needle with Encoding.ASCII.GetBytes and delegates to the byte[] overload. (BR-053)
  2. Initialise found = -1. Proceed only if the haystack is non-empty, the needle is non-empty, start <= input.Length - searchFor.Length, and the haystack is at least as long as the needle; otherwise return -1. (BR-054)
  3. Iterate i from start to input.Length - searchFor.Length.
  4. If maxBytesToSearch > 0 and i > maxBytesToSearch, break out of the loop — a scan cap for large payloads. (BR-055)
  5. When input[i] equals the needle's first byte, compare the remaining needle bytes one by one; on the first mismatch abandon this position.
  6. On a full match, record found = i and break.
  7. Return found.

Process flow

The following diagram visualizes this operation's control flow.

flowchart TD
    Start(["Search called with<br>byte[] or string needle"]) --> Overload{"String overload?"}
    Overload -->|Yes| ToBytes["Convert needle to bytes<br>via Encoding.ASCII"]
    Overload -->|No| Guard
    ToBytes --> Guard["Initialise found = -1"]
    Guard --> GuardCheck{"Haystack/needle non-empty<br>and start offset valid?"}
    GuardCheck -->|No| ReturnNeg1(["Return -1"])
    GuardCheck -->|Yes| Loop["Iterate i from start to<br>input.Length - searchFor.Length"]
    Loop --> CapCheck{"maxBytesToSearch > 0<br>and i > max?"}
    CapCheck -->|Yes| BreakCap["Break loop (scan cap)"]
    CapCheck -->|No| FirstByte{"input[i] equals<br>needle's first byte?"}
    FirstByte -->|No| NextI["Advance to next i"]
    NextI --> Loop
    FirstByte -->|Yes| Compare{"Remaining needle<br>bytes match?"}
    Compare -->|No| NextI
    Compare -->|Yes| RecordFound["Record found = i;<br>break loop"]
    RecordFound --> ReturnFound(["Return found"])
    BreakCap --> ReturnFound

Sources

  • Common/SAIF.Common/Extensions/ByteExtensions.cs