Packet Analysis
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.
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.
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.
- 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.
- 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.
- Compare: drop the two sets into A and B of Text Comparison and see which offsets the difference table lands on.
- Verify: change the value at that offset in Packet Edit, replay it, and watch whether the program or server reacts the way you expect.
- Rule out interference: if the server rejects your edit, work through section 04 to check for a checksum or encryption.
- 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:
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.
Doing it in WPE x64
- 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.
- 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. - Capture set two: change the value to
90, repeat the same action, right-click and choose Add to Text B. - Compare: switch to Text Comparison and press Compare — the difference table names exactly which byte positions changed.
- 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.
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.
| Field | How to recognise it | Effect when replaying | What to do in WPE |
|---|---|---|---|
| Sequence / counter | strictly increasing, usually by 1; resets when the connection restarts | if it does not advance, the server treats the packet as a duplicate and drops it | right-click the filter modify row and choose Enable Progression, step 1, with carry-over for overflow |
| Timestamp | grows with the clock, identical across packets in the same second; usually 4 or 8 bytes | a stale timestamp is rejected by the server | never hard-code it — leave the cell blank in the search row so the original value passes through |
| Nonce / session ID | no pattern at all, but constant for the life of one connection | useless on a new connection — a replay the next day always fails | skip the cell with the wildcard ** in the search row, or mark it Random |
| Length field | its value is exactly the byte count of the packet or the payload | an edit that leaves the length stale throws off the parser | prefer same-length replacements; if the size changes, update the length field with it |
| Checksum | flip any byte and it changes too, with no obvious pattern | without recomputing it, the whole packet is discarded | see the next section |
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.
What to do in each case
| Verdict | What you can do |
|---|---|
| Plaintext | work 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 |
| Checksummed | work 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 / HTTPS | do 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 encryption | nothing 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 |
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:
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 bytes | What it is | What to do |
|---|---|---|
16 03 01 / 16 03 03 | TLS handshake (ClientHello / record layer) | encrypted — switch to Proxy Mode to decrypt |
17 03 03 | TLS application data | as above |
47 45 54 20 (GET )50 4F 53 54 (POST) | plaintext HTTP request | Proxy Mode shows it as text directly |
48 54 54 50 2F (HTTP/) | HTTP response | as above |
01 00 or 81 80 at byte 3 | DNS query / response | a UDP type — capture it with RecvFrom / SendTo |
| the same few bytes recurring at the front | the magic-number head of a custom protocol | exactly what the head field in UnPack wants |
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 it | Where it is in WPE x64 2.1.8 |
|---|---|
| SEARCH | the first row, Search, of the data grid in Filter Edit (pale yellow) |
| MODIFY | the second row, Modify, of the same grid (yellow) |
| normal mode | Mode → Normal, matching at fixed offsets |
| progressive mode | Mode → Advanced, sliding search for a signature. This is not the Progression mark of 2.1.8! |
| replace from the start of the packet | Advanced mode, start from → the beginning of the packet |
| replace from where the match was found | Advanced mode, start from → the matched position |
| packet size / length limit | Specify type → Length, which accepts ranges such as 0-99;100 |
| filter | the Filter feature. Do not confuse it with Leach Setting, which only controls what the list displays |
| send list / replay | Send List, with Packet Edit for replaying one packet |
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
□ 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)
- 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. - The window appears inside the target process. Go to Menu → Hook Settings and tick only Send and Recv to cut the noise.
- Menu → Leach Setting: choose Only Display, tick Port, and enter the server port.
- Press Start — this also resumes the suspended target process.
- 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
- Capture once with the value at
100, right-click → Add to Text A. - Change the value to
90, repeat the action, right-click → Add to Text B. - Switch to Text Comparison and press Compare — the difference table names exactly which bytes changed.
- 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)
- Proxy Mode → Proxy Settings: tick Enable HTTP proxy (port 1081 by default).
- Press Start; once the System Log reports the WPE64 certificate installed, the local machine is ready.
- For a phone or another machine: pick a certificate format in Proxy Settings → Export Cert → install it as a trusted root certificate on that device.
- Point the device's HTTP proxy at
<WPE machine IP>:1081. - In the Proxy List, packets of the
HTTPS request / responsetypes show as plain text in the panel below.
Scenario 4 · Swap a live JS file for a local one (for debugging)
- Proxy Mode → Menu → Map Settings → tick Enable Map Local → add an entry:
protocolHttps, hostcdn.example.com, port443, remote path/app.js - Local file: drop in your edited
app.js. - Save and restart the proxy service. From then on the whole response body for that URL is replaced by the local file.
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
- Proxy Settings: tick Enable SOCKS5 proxy (1080) and Enable authentication; leave Auto detect on so it listens on every adapter.
- Account List → Menu → 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. - 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.
- Remote MGT Settings: enable it on port 88 with an administrator account, and you can check who is online from a browser.
- Press Start to bring the service up.
Scenario 6 · Publish nodes and notices to the WPEProxyCap accelerator
- Complete scenario 5 first, so a working SOCKS5 service and accounts exist.
- Enable Remote MGT, say on port 88.
- WPC Config → server list: add a server with a name, your public IP, port 1080, and the registration, password-recovery and verification URLs.
- Give it rules — for example
PROCESS-NAME / game.exe / PROXY— and a finalMATCH / DIRECTto catch everything else. - Add a notice of the maintenance type to the notice list.
- Clients then fetch the node list from
http://<public IP>:88/ProxyCap/GetServerList. - 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.
/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
- Use scenarios 1 and 2 to find the packet the feature sends, then right-click → Add to Filter List.
- Double-click the new filter, set the action to Intercept, and tick Send as the packet type.
- 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.
- Save, switch the filter on in the Filter List, and watch the execution count to confirm it matches.