EN
v2.1.7
WPE_TUTORIAL_V2 // 05_ANALYSIS

Packet Analysis

Tutorial Rev · 2.1.8 beta

The earlier chapters cover how to drive the software. This one covers what to do when you meet a protocol you know nothing about — reading the structure of a packet, pinning down the one byte you want, and proving the change really took effect.

// What this chapter is

No buttons are explained here — this is about method. Every feature it uses is documented in an earlier chapter, and this one only points at which feature and which section.
Read the Filters chapter first.

Quick start // from a wall of hex to a field you can edit

Faced with a protocol you have never seen, working in this order beats staring at hex. Each step is expanded on later in the chapter.

  1. Narrow it down: use Leach Setting to block irrelevant traffic by port or length, so the list holds dozens of rows instead of tens of thousands.
  2. Run a controlled experiment: change exactly one variable in the game or program — press one button, change one number — and capture two sets of packets.
  3. Compare: drop the two sets into A and B of Text Comparison and see which offsets the difference table lands on.
  4. Verify: change the value at that offset in Packet Edit, replay it, and watch whether the program or server reacts the way you expect.
  5. Rule out interference: if the server rejects your edit, work through section 04 to check for a checksum or encryption.
  6. Make it permanent: once the pattern holds, turn the manual edit into a filter so it applies on its own.

01 · What a packet looks like

Nearly every custom binary protocol assembles its packets from the same handful of parts. Recognising them is where all analysis starts:

01The parts of a typical binary packet · not every protocol has all of them, but the order is usually this.
one complete packet, in hex 01 00 00 00 26 1A 05 00 3F 4A 5B C3 7F … payload … 9C 4D 0 – 23 – 45 – 6 7 – 89 – …last 2 bytes ① Head / magic number never changes; it is how you confirm a packet belongs to this protocol → UnPack "head" · a filter's "packet head" ② Length total packet size — what splits a coalesced stream → UnPack "length" (byte range, big-endian) ③ Opcode / command says whether this is login or movement → the main anchor in a search row ④ Sequence / timestamp counts up per packet or tracks the clock — the usual trap when replaying → a filter's Progression mark ⑤ Payload the actual data — what you want to change is usually in here → a filter's search row + modify row ⑥ Checksum CRC or sum — recompute after editing → see section 04 of this chapter
// Useful straight away

Identify just the head and the length and you can go to UnPack in Proxy Mode and slice a coalesced TCP stream back into individual packets — everything downstream gets much easier.

02 · Locating a field in four steps

This is the core method: do not guess — force the field out with a controlled experiment.

02Locating by difference · make one controlled change and watch which bytes follow it.
① One controlled changeone variable only ② Two sample setsbefore / after ③ Compare byte by byteText Comparison tool ④ Verify in reversechange it back, watch the effect fails → try another variable Rule of thumb: change one variable at a time. Change two and the differing bytes appear in two places at once. Rule of thumb: capture the same action 3 to 5 times. Positions that change every single time are sequence numbers or timestamps. Rule of thumb: narrow first, then look closely. Filter out the noise by packet head or length — a clean list is far easier to compare.

Doing it in WPE x64

  1. Narrow the list: in Leach Setting choose Only Display and pick out the packets you want by port or head, so the list is clean to begin with.
  2. Capture set one: have the target perform the action once — say with the value at 100 — then right-click the packet and choose Add to WareHouse to archive it, and Add to Text A.
  3. Capture set two: change the value to 90, repeat the same action, right-click and choose Add to Text B.
  4. Compare: switch to Text Comparison and press Compare — the difference table names exactly which byte positions changed.
  5. Verify: in Packet Edit set those bytes to a third value, send it, and see whether the target reacts as predicted. If it does, the field is confirmed.
// Why archive to the WareHouse

The WareHouse keeps samples byte for byte, and clearing the list — manually or automatically — does not touch them. Pinning down one field often takes a dozen comparisons, so archiving as you go saves a lot of re-capturing. If the head is fixed, turn on auto-store and let it collect for you.

03 · Spotting the fields that change every time

Comparing samples, you will notice that some bytes differ on every run even when you change nothing. They are noise, and unless you rule them out first you will mistake them for the field you are after.

FieldHow to recognise itEffect when replayingWhat to do in WPE
Sequence / counterstrictly increasing, usually by 1; resets when the connection restartsif it does not advance, the server treats the packet as a duplicate and drops itright-click the filter modify row and choose Enable Progression, step 1, with carry-over for overflow
Timestampgrows with the clock, identical across packets in the same second; usually 4 or 8 bytesa stale timestamp is rejected by the servernever hard-code it — leave the cell blank in the search row so the original value passes through
Nonce / session IDno pattern at all, but constant for the life of one connectionuseless on a new connection — a replay the next day always failsskip the cell with the wildcard ** in the search row, or mark it Random
Length fieldits value is exactly the byte count of the packet or the payloadan edit that leaves the length stale throws off the parserprefer same-length replacements; if the size changes, update the length field with it
Checksumflip any byte and it changes too, with no obvious patternwithout recomputing it, the whole packet is discardedsee the next section
// The classic failure

Edit one byte by hand, send it once, and it works; send it a few times in a row and the server ignores all of them. Nine times out of ten a sequence field is not advancing. That is exactly what a filter's Progression mark is for — it adds 1 on every match.

04 · Telling encryption and checksums apart

Before spending hours on byte-level analysis, spend two minutes working out which category the protocol falls into. It saves a lot of wasted effort.

03Three quick tests · run them in order and you will know within minutes.
① Readable text in the panel? yes Plaintext protocolanalyse it directly — the easy case no ② Twice — bodies identical? identical Binary plaintext · maybe encodedtry the XOR tool different ③ Flip a byte and sendrejected → checksummedaccepted → fully encrypted Test ① — the character column right of the data panel: readable fragments such as HTTP, JSON, hostnames or player names mean plaintext. For test ② just run the two samples through Text Comparison. Identical means no randomisation, which makes the analysis far easier. For test ③ flip any payload byte in Packet Edit and replay: no server reaction means a checksum caught it; normal handling means none. Note: HTTPS and TLS count as fully encrypted, but Proxy Mode can decrypt them — see below.

What to do in each case

VerdictWhat you can do
Plaintextwork through the four steps in section 02; filters can rewrite it freely
Simple encoding (XOR or bit shift)try single-byte and repeating keys in XOR. A multi-byte key is applied cyclically, which is exactly what a rotating key needs
Checksummedwork out the algorithm first — flip one byte and watch how the check bytes move — then recompute after each edit. If you cannot, all that is left is replaying packets unchanged
TLS / HTTPSdo not fight the ciphertext in Inject Mode. Switch to Proxy Mode, enable the HTTP proxy, and read the plaintext the man-in-the-middle produces
Custom strong encryptionnothing to be done at the packet layer. Your options are replaying it untouched (Send List) or going back to Inject Mode and working on an API that runs before the encryption
// A shortcut people miss

Inject Mode hooks the WinSock send and receive functions, so what you get is the final bytes the program is about to put on the wire. If the program encrypts at the application layer, that encryption has already happened by the time the hook runs — switching to Proxy Mode gains you nothing. If instead the encryption is transport-level like TLS, the proxy's man-in-the-middle strips it off. Work out which layer the encryption sits at, then choose the mode.

05 · The full workflow, analysis to edit

Chaining together the features from the earlier chapters, one complete job looks like this:

04The full workflow · which section of the tutorial covers each step.
1 · CaptureInject or Proxy 2 · Narrow downLeach Setting + UnPack 3 · Store samplesWareHouse / auto-store 4 · Locate the fieldText Comparison 5 · Verify by handreplay via Packet Edit 6 · Turn it into a filtersearch row + modify row 7 · Handle volatile bytesProgression / Random / Exclude 8 · Watch the logfilter log / statistics 9 · Automatechained execution / Robot wrong? go back and fix it Do not skip step 5. A filter runs automatically, so a wrong rule keeps acting on every packet — send one by hand from Packet Edit first. Step 8 is about the execution count: rising means the rule matched, static means the conditions are wrong — the fastest check there is.

06 · Recognising a protocol by its first bytes

Captured a pile of binary and no idea what it is? Look at the first few bytes — many protocols give themselves away instantly:

Leading bytesWhat it isWhat to do
16 03 01 / 16 03 03TLS handshake (ClientHello / record layer)encrypted — switch to Proxy Mode to decrypt
17 03 03TLS application dataas above
47 45 54 20 (GET )
50 4F 53 54 (POST)
plaintext HTTP requestProxy Mode shows it as text directly
48 54 54 50 2F (HTTP/)HTTP responseas above
01 00 or 81 80 at byte 3DNS query / responsea UDP type — capture it with RecvFrom / SendTo
the same few bytes recurring at the frontthe magic-number head of a custom protocolexactly what the head field in UnPack wants
// Filtering fast

Once you know the signature, combine Find Hex in Search Packet with a regular expression to pull them out in one pass — ^16 03 for every TLS record, ^01 00 0A for one particular custom packet.

07 · Legacy WPE tutorials, translated

Most WPE tutorials circulating online were written more than a decade ago against the original WPE or WPE Pro. The thinking still applies, but the vocabulary and the screen positions do not match 2.1.8. Check this table before following one:

What the old tutorial calls itWhere it is in WPE x64 2.1.8
SEARCHthe first row, Search, of the data grid in Filter Edit (pale yellow)
MODIFYthe second row, Modify, of the same grid (yellow)
normal modeMode → Normal, matching at fixed offsets
progressive modeMode → Advanced, sliding search for a signature. This is not the Progression mark of 2.1.8!
replace from the start of the packetAdvanced mode, start from → the beginning of the packet
replace from where the match was foundAdvanced mode, start from → the matched position
packet size / length limitSpecify type → Length, which accepts ranges such as 0-99;100
filterthe Filter feature. Do not confuse it with Leach Setting, which only controls what the list displays
send list / replaySend List, with Packet Edit for replaying one packet
// The one word that trips everyone up

Progressive mode in the old tutorials means Advanced mode in 2.1.8 — floating matching against a signature.
2.1.8's own Progression is something else entirely: a mark you put on one cell of the modify row so that the byte is incremented by the step on every match, which is how you deal with sequence fields.
The two are unrelated; keep them apart when reading old material.

Beyond vocabulary, the real differences

  • The old WPE only offered injection; 2.1.8 adds Proxy Mode, which makes HTTPS and mobile devices far easier to capture.
  • The old version had no wildcards; search cells in 2.1.8 accept nibble wildcards such as 4* and *A, which handle floating fields with much less work.
  • The old version had no Exclude; in 2.1.8 you can mark a search cell Exclude, meaning it matches only when the byte is not this value.
  • The old version needed someone watching; 2.1.8 has chained execution, so a match can fire a send, a robot or an archive on its own.
  • The old version had one configuration per machine; 2.1.8 supports multiple instances, each target with its own independent configuration.

08 · A checklist before you start

// Run through this first

□ Should this target go through Inject or Proxy? (comparison)
□ Are the right functions ticked in Hook Settings? Stop and Start again after changing them
□ Have you used Leach Setting to keep the noise out of the list?
□ Is TCP coalescing packets? Should UnPack be configured first?
□ Are your samples in the WareHouse? An auto-clear halfway through wastes the whole capture
□ Have you captured the same action at least three times? Otherwise you cannot tell a real field from a sequence number
□ Did you check for a checksum before editing?
□ After writing the filter, did you watch the execution count to confirm it actually matched?

09 · Seven worked scenarios

These string the whole tutorial's features together around real tasks. Each scenario runs from nothing to working, with the details covered in the chapter it points at.

Scenario 1 · Capture a client's login packet (Inject Mode)

  1. Start screen → Inject Mode → Select Program, pick the target exe → Inject.
    Use Select Program rather than picking a running process from the list, or you will miss the packets sent during startup.
  2. The window appears inside the target process. Go to MenuHook Settings and tick only Send and Recv to cut the noise.
  3. MenuLeach Setting: choose Only Display, tick Port, and enter the server port.
  4. Press Start — this also resumes the suspended target process.
  5. Log in and watch the list. When you find the packet, right-click → Add to WareHouse to archive it.

Scenario 2 · Find the offset of a value in a packet

  1. Capture once with the value at 100, right-click → Add to Text A.
  2. Change the value to 90, repeat the action, right-click → Add to Text B.
  3. Switch to Text Comparison and press Compare — the difference table names exactly which bytes changed.
  4. Change those bytes in Packet Edit, replay to verify, and only then turn it into a filter.

This is the smallest possible instance of the four-step method in section 02. If the position drifts between captures, switch to Advanced mode and match on a signature instead.

Scenario 3 · Read HTTPS in the clear (Proxy Mode)

  1. Proxy Mode → Proxy Settings: tick Enable HTTP proxy (port 1081 by default).
  2. Press Start; once the System Log reports the WPE64 certificate installed, the local machine is ready.
  3. For a phone or another machine: pick a certificate format in Proxy Settings → Export Certinstall it as a trusted root certificate on that device.
  4. Point the device's HTTP proxy at <WPE machine IP>:1081.
  5. In the Proxy List, packets of the HTTPS request / response types show as plain text in the panel below.

Scenario 4 · Swap a live JS file for a local one (for debugging)

  1. Proxy Mode → MenuMap Settings → tick Enable Map Local → add an entry:
    protocol Https, host cdn.example.com, port 443, remote path /app.js
  2. Local file: drop in your edited app.js.
  3. Save and restart the proxy service. From then on the whole response body for that URL is replaced by the local file.
// Why not a filter

Filters do not apply to the HTTP or HTTPS types — neither appears among the packet types. Web resources always go through Map Settings.

Scenario 5 · Run WPE as a SOCKS5 server with accounts

  1. Proxy Settings: tick Enable SOCKS5 proxy (1080) and Enable authentication; leave Auto detect on so it listens on every adapter.
  2. Account ListMenu → create accounts in bulk: prefix vip, 50 of them, password length 8, link limit 5, with an expiry date → preview → save → right-click to export to Excel for distribution.
  3. FireWall Settings: tick Enable FireWall and choose BlackList mode; under FireWall rules turn on auto-blocking for failed authentication and a 30-minute ban for unsupported SOCKS versions.
  4. Remote MGT Settings: enable it on port 88 with an administrator account, and you can check who is online from a browser.
  5. Press Start to bring the service up.

Scenario 6 · Publish nodes and notices to the WPEProxyCap accelerator

  1. Complete scenario 5 first, so a working SOCKS5 service and accounts exist.
  2. Enable Remote MGT, say on port 88.
  3. WPC Config → server list: add a server with a name, your public IP, port 1080, and the registration, password-recovery and verification URLs.
  4. Give it rules — for example PROCESS-NAME / game.exe / PROXY — and a final MATCH / DIRECT to catch everything else.
  5. Add a notice of the maintenance type to the notice list.
  6. Clients then fetch the node list from http://<public IP>:88/ProxyCap/GetServerList.
  7. For WPC's one-click subscription to find this machine on its own, request a subscription ID bound to the address from the subscription server. For your own testing the direct address above is enough.
// Security note

/ProxyCap/* is a public, unauthenticated endpoint: anyone who can reach that port can read the node list. Restrict the source addresses with a firewall before exposing it to the internet.

Scenario 7 · Block the packets behind one feature

  1. Use scenarios 1 and 2 to find the packet the feature sends, then right-click → Add to Filter List.
  2. Double-click the new filter, set the action to Intercept, and tick Send as the packet type.
  3. In the search row, keep only the bytes that uniquely identify that feature and clear the rest, so other packets are not caught by mistake.
  4. Save, switch the filter on in the Filter List, and watch the execution count to confirm it matches.