Skip to content

Convert CDP message directly to JSON without filtering - #262

Merged
evi0s merged 6 commits into
evi0s:mainfrom
Redbeanw44602:no-filtering
Aug 24, 2026
Merged

evi0s merged 6 commits into
evi0s:mainfrom
Redbeanw44602:no-filtering

Conversation

@Redbeanw44602

Copy link
Copy Markdown
Contributor

I submitted the Linux support yesterday: #261

But I later discovered that it seemed to have some issues, such as: no network events, inability to view the source code, and the console constantly displaying “access violation” errors:

[frida client] {
  type: 'error',
  description: 'Error: access violation accessing 0x0',
  stack: 'Error: access violation accessing 0x0\n    at onLeave (/script1.js:62)',
  fileName: '/script1.js',
  lineNumber: 35,
  columnNumber: 1
}

After printing inputValue, I noticed that in some cases it appears to point to an invalid memory address.

0x70403fa4000 <- OK
0x31323a226469227b <- Invalid?

To figure out the cause, I looked into the SendToClientFilter function, but it’s too complex. I think it’s a filter designed to help WeChat prevent debuggers from seeing certain specific things, but I don’t know why it causes *a1 to be written to an invalid address.
But I discovered something else interesting: under certain circumstances, messages aren't passed through the filter but are converted directly to JSON.

image

So I tried converting the message directly to JSON and returning it without filtering it first, and it worked great!

image

I don't think it's harmful to leave it unfiltered. 😏


In addition, I noticed changes to the patchCDPFilter function. Please note that Linux uses the SysV ABI, and the first two integer parameters are passed via RDI/RSI. I recommend using Frida’s cross-platform method for accessing parameters.


If you have any ideas, please let me know!

@evi0s

evi0s commented Aug 22, 2026

Copy link
Copy Markdown
Owner

In addition, I noticed changes to the patchCDPFilter function. Please note that Linux uses the SysV ABI, and the first two integer parameters are passed via RDI/RSI. I recommend using Frida’s cross-platform method for accessing parameters.

You were right, it's my oversight.

To figure out the cause, I looked into the SendToClientFilter function, but it’s too complex. I think it’s a filter designed to help WeChat prevent debuggers from seeing certain specific things, but I don’t know why it causes *a1 to be written to an invalid address.

Yes. On Windows it's later checked by the first parameter, as shown below. I guess it's similar to the macOS's implementation. I prefer not introducing structural changes (i.e., add more address offset) that could add more maintenance efforts. If possible, could you please test use macOS's patch strategy instead? Really appreciate your interests and efforts.

Windows:

Screenshot 2026-08-22 at 11 29 35

macOS:

Screenshot 2026-08-22 at 11 31 04

@Redbeanw44602

Copy link
Copy Markdown
Contributor Author
image

Hello, thank you for your prompt reply. I just tested the macOS strategy, and the access violation is gone, but the requests are still incomplete, and the source view isn't working either.

The Protocol Monitor shows that a significant number of requests did not receive the main message (for example, they received only Network.requestWillBeSentExtraInfo but not Network.requestWillBeSent). I believe the CastToJson patch is unavoidable on Linux, or that the effort required to resolve the filtering issue would be far greater than the effort needed to find the CastToJson offset. Moreover, CastToJson is very easy to locate, and if it isn’t needed on Windows or macOS, it can be made optional.

Also... I don't seem to understand the meaning of *(a1 + 8). To me, a1 appears to be a std::string, and the 8-byte offset might be the size of the string when it's allocated on the heap—it seems unlikely that this would ever equal 6. After I removed the logic that sets it to 0, there didn't seem to be any noticeable change. 🤔

@evi0s

evi0s commented Aug 22, 2026

Copy link
Copy Markdown
Owner

I see. I might see the issue here. In your address offset config, the CDPFilterHookOffset was configured to that function body, instead of the actual filter function, correct? That's why the replace the entire function to the castToJSON worked in your case. In my original design, the function to be patched should be 0xBCAAFD0, instead of 0xBCB4C40. Could you please try again if that worked, by changing the CDPFilterHookOffset to 0xBCAAFD0 with macOS's patch strategy? Thank you so much for your time.

btw, your workaround should indeed work and look pretty intuitive, but since currently we've already had so many versions behind, adding this would introduce different patching strategy in code. My intuition is keeping the code as simple as possible, without adding major structural changes. Thanks for your understanding.

Comment thread frida/config/linux/addresses.14978.json Outdated
@Redbeanw44602

Redbeanw44602 commented Aug 23, 2026 •

Copy link
Copy Markdown
Contributor Author

Oh, I see. That explains everything. I tested your method, and it seems to be working fine for now.

However, it should be clarified that 0xBCAAFD0 is not a filter function; the function responsible for filtering is likely 0xBCB4C40 (SendToClientFilter). 0xBCAAFD0 appears to be more of a parser for a specific format—I believe it’s CBOR. I’m not sure what the specific significance of *(retptr + 8) == 6 is—perhaps it’s some kind of type marker. Hooking 0xBCAAFD0 might be a viable solution, but since it’s used by several other functions as a general-purpose CBOR parser, I’m unsure if this would pose any risks. Therefore, I suggest gradually migrating the project to CastToJson while keeping it as an optional feature to ensure backward compatibility.

The CDP format library used by Chromium, but I'm not sure if 0xBCAAFD0 is the one.

Please let me know your thoughts!

@evi0s

evi0s commented Aug 23, 2026

Copy link
Copy Markdown
Owner

Gotcha, that makes sense. Then the current patching strategy is actually tricking the filter function to believe the incoming message is a specific type, which triggers the short-circuit path (please correct me if I'm wrong). I checked the cross-refs of that function and I indeed found three more references. In fact, there's another filter function I previously haven't noticed before (devtools_message_filter_webview.cc) might also be affected by this hook point as well. I'm not pretty sure if this is related to debugging other targets (or not related at all), but it seems to be a universal way to take care all of these cases as long as a proper check exists.

Anyways, personally I'm still not convinced to make this structural change, since there's saying that, if it works, don't touch it. This's also the reason that the previous PR for macOS adaptation wasn't merged at the beginning, because the structural changes were not sound enough, until your last PR (thanks again btw!). Hope you could understand that. Someday, if WMPF introduced more related code causing the existing patching strategy broken, we can then pivot to other patching strategies like your proposed one. Thanks again for your effort and understanding.

@Redbeanw44602

Copy link
Copy Markdown
Contributor Author

Okay, I agree with you. I'll update the code later today.

I have one more question: Does the macOS logic work on Windows? Placing the return value as the first input parameter is a compiler optimization (RVO); generally, the return value and the first input parameter point to the same thing, so I’d like you to test this. If it works, we can remove some of the conditional checks.

Thanks for your patience and participation!

@evi0s

evi0s commented Aug 23, 2026

Copy link
Copy Markdown
Owner

Thanks so much for your understanding!

I have one more question: Does the macOS logic work on Windows? Placing the return value as the first input parameter is a compiler optimization (RVO); generally, the return value and the first input parameter point to the same thing, so I’d like you to test this. If it works, we can remove some of the conditional checks.

This makes perfectly sense. I just removed the check and tested it, and it worked! However, there's still a difference that, the value on Windows is passed by pointer (of a stack variable), so you'll need to use retval.readPointer().add(8).readU32() instead of the macOS's using direct value retval.add(8).readU32(). So I guess we'll still need special check for macOS, but at least the stuff in onEnter can be dropped.

@Redbeanw44602

Copy link
Copy Markdown
Contributor Author

The documentation looked a bit outdated, so I updated it. Please check to see if it works properly on Windows; I think this PR is ready to be merged.

@evi0s

evi0s commented Aug 24, 2026

Copy link
Copy Markdown
Owner

Looks fantastic! Thank you again for your contribution!!

@evi0s
evi0s merged commit a79c4e8 into evi0s:main Aug 24, 2026
@Redbeanw44602
Redbeanw44602 deleted the no-filtering branch August 25, 2026 02:19
evi0s added a commit that referenced this pull request Sep 19, 2026
* hook.js: CDPFilter patch method migrated to function replacing. credit
  @Redbeanw44602, PR #262
* hook.js: structural changes. more necessary offsets are introduced,
  including remotedebug mode, and back connecting URL
* platform win32: version extraction method update
* deps: bump frida to the latest
* TODO: auto-detect should be updated
* TODO: docs should be updated as well
@evi0s

evi0s commented Sep 19, 2026

Copy link
Copy Markdown
Owner

looks like this day has come already which is much faster than I thought. I've migrated the win32's CDP patch method to yours and tested, but seems like win32's calling convention is probably different with darwin or linux. could you please test the latest CDP patch method on linux if you are available? really appreciated!

@Redbeanw44602

Redbeanw44602 commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor Author

Hello, I'd be happy to help. But the WeChat on my Linux has already been updated to 4.1.13.9, so it seems we don't have the latest WMPF support yet (the latest internal version is 2.5.6.25665).

#272 looks like something AI-assisted; I'm not sure if it's usable, but I'll submit a patch tomorrow.

@evi0s

evi0s commented Sep 19, 2026

Copy link
Copy Markdown
Owner

thank you so much for your help!

#272 looks like something AI-assisted

right, and i reviewed the code but the author wasn’t responding. we probably need another way to detect the WMPF version on linux; windows also has similar changes of version detection btw since the WeChatAppEx binary was moved out from the runtime directory of each version (commit 2970a6c).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants