4.9 KiB
DFP Bootstrap Design
Goal
Add a pure Python DFP bootstrap layer that consumes DeviceProfile and builds
DFP/unifiedId request material without depending on APP runtime, HAR templates,
Frida logs, or scripts under out/.
The first deliverable is deterministic dry-run request construction. Online POST and profile update are added only after dry-run form material is isolated, tested, and stable.
Current Evidence
Recovered relationships and algorithms already available in core/:
core.enc_data.kwsg_10400_raw()builds the 10400deviceInfoenvelope.core.dfp_sign.sign_dfp_form()builds 10405sign.core.device_profile.DeviceProfileholds localdid/oDid/rdid/egidstate.egidis returned by/rest/infra/gdfp/report/kuaishou/android.- cloud
did/cdid_tagcomes from unifiedId fetch/repair responses.
Useful prototype code currently lives under out/:
out/dfp_sq0_proto.pyout/build_dfp_lite_knn.pyout/build_dfp_full_knn.pyout/build_dfp_fetch_form.pyout/build_dfp_repair_form.pyout/build_dfp_check_repair_form.pyout/build_dfp_report_form.pyout/dfp_protocol_client.py
Phase 2 migrates the reusable pieces into core/ and leaves analysis scripts in
out/ as historical evidence only.
Scope
Included
- Encode DFP sq0 protobuf bytes for lite and full kNN maps.
- Build lite and full kNN maps from
DeviceProfileplus optional static environment/profile fields. - Build signed forms for:
unifiedId/fetch/androidunifiedId/checkRepairunifiedId/repair/androidgdfp/report/kuaishou/android
- Export request specs with URL, headers, ordered form, body, and debug hashes.
- Add optional online POST client after dry-run builders pass tests.
- Parse cloud DID / did tag / egid responses and write them back through
DeviceProfile.apply_cloud_identity().
Excluded
- Live APP instrumentation.
- HAR runtime templates.
- Mutating
main.pytask flow. - Claiming
egidis locally generated.
Architecture
DeviceProfile
-> core.dfp_knn.build_lite_knn()
-> core.dfp_sq0.encode_sq0_device_info()
-> core.enc_data.kwsg_10400_raw()
-> core.dfp_forms.build_unified_fetch_form()
-> core.dfp_forms.build_unified_check_repair_form()
-> core.dfp_forms.build_gdfp_report_form()
-> core.dfp_client.post_request() # online only
-> DeviceProfile.apply_cloud_identity()
core/dfp_sq0.py
Pure sq0 protobuf encoder/decoder.
Responsibilities:
- load embedded lite/full key-to-proto-tag schema
- encode ordered kNN string maps
- decode fields for tests and diagnostics
core/dfp_knn.py
Build DFP plaintext kNN maps.
Responsibilities:
- build lite 33-key map
- build full 119-key map
- compute
k14CRC - use
DeviceProfilefor identity fields:k31android idk66oDid suffixk83current cached egid or empty first-run valuek107did tagk112cache marker if suppliedk93.28gRdi2
core/dfp_forms.py
Build signed form objects.
Responsibilities:
- wrap sq0 bytes in 10400
deviceInfo - Java-style base64 and form encoding
- preserve request form order
- use
core.dfp_sign.sign_dfp_form() - expose
DfpRequestSpec
core/dfp_client.py
Optional online client.
Responsibilities:
- POST request specs using
requests - parse JSON safely
- return structured
DfpResponse - update
DeviceProfileonly when response fields pass validation
tools/new_device.py
Extends current CLI:
--dfp-dry-run: write DFP request material without sending.--online: send DFP bootstrap requests and update saved profile.--profile PATH: load an existing profile instead of creating a new one.
Error Handling
- Missing required identity fields raise
ValueError. - Invalid DFP response fields are recorded and not applied.
- Online mode records HTTP status, JSON parse failures, and business result.
- Request builders never silently omit known empty fields; empty strings remain present when the Java form includes the key.
Test Strategy
Use TDD and unittest because this project does not currently depend on
pytest.
Required checks:
- sq0 encoder keeps key order and skips empty values in the same way as the prototype.
- k14 CRC changes when any mapped value changes.
- lite kNN uses
DeviceProfileidentity fields. - form builders preserve known form order.
- DFP sign input material matches
core.dfp_signrules. - dry-run request specs produce deterministic body ordering.
- online response parser only applies valid
cloud_did/did_tag/egid.
Milestones
- Dry-run migration:
core/dfp_sq0.pycore/dfp_knn.pycore/dfp_forms.py
- CLI integration:
tools/new_device.py --dfp-dry-run
- Online bootstrap:
core/dfp_client.pytools/new_device.py --online
- Request/profile persistence:
- save request material under
out/devices/<profile>/dfp_*.json - save updated profile JSON after accepted server identity response
- save request material under