Location>code7788 >text

Reverse WeChat (VI)

Popularity:601 ℃/2024-09-09 23:10:01

Previous review, reverse analyzing mojo,, wmpf_host_export.dll, and how to get the remote or receiver of a c++binding through mojoCore and call their functional interfaces.   

This article describes how to sniff Sniff on the applet mojoIPC, how to pass the grab bag applet https, how to open the applet devtool, who is in charge of the vconsole configuration.

This post is at the blogspot address/bbqzsl/p/18370679

How to sniff mojoIPC

borrow sth. for another useConverted. Retrofit to. Although it is a C# project, it is also mainly using Win32API, and it is not difficult to transform the main logic into c++. The main use of the program is to perform sniff. program scanning to find out the mojom related service names, and their method hash name. and then with the code silo of the mojom file mapping to generate the mapping table. The wireshark lua analysis script is provided. Knowing this, you can refactor on demand. Scan, wmpf_host_export.dll, to release its own service interface. Find out the chromium version and synchronize the lua scripts. Add your own analysis to the lua script.

How to trace mojoIPC and intercept IOCP.

In addition to sniff mojoIPC, it can also be tracked by doing an io intercept for each mojo process.

Now let's talk about tracking mojoIPC by intercepting io first, and then continue with sniff mojoIPC later.

The windows platform mojo uses IOCP for overlapped operations. So theoretically trace IOCP can basically trace all the data of the channel. For the NamedPipe set by mojo, WriteFile will surely block pending, and get the completion event at IOCP. But ReadFile will not, but can either succeed immediately or get pending, which is what I found in the actual trace. In other words, if you only trace IOCP, you can only get part of the PendingRead and all the Writes, so you have to trace Read and IOCP.CompletionKey is ChannelWin, which holds the temporary Pending Buffer. ReadContext or WriteContext, so that you can distinguish between the completion of the operation is to read or write.ReadContext use CircularBuffer, out of the effective Buffer can be.WriteContext use Buffer Pointer List, to take the first Buffer queue. Saved on the video, the database can use some class mongodb lightweight database. Or through a NamedPipe, Buffer write WireShark Frame, combined, output to WireShark and save. WireShark convenient and visualization tools, the disadvantage is to carry additional information is limited, and can not support DataPipe, because there is no way to sniff shared memory. While trace IOCP, you can use mongodb-like document records, you can flexibly carry a variety of information. At the same time, you can also read out the contents of the DataPipe SharedBuffer. One thing to note is that a read/write operation may pack more than one Message, so it must be disassembled. This approach, there is no ready-made code or tools, everything has to be done by themselves, a lot of work. In addition, there is a shortcoming, the capture of the operation in fact can not accurately distinguish between data read or write operations. Use your own implementation of the main logic will be clear. Just coincidentally, only the packet marked as Read record. But in fact, the same packet must be captured twice, a write pipeline, a read pipeline, but sometimes one of them will be missed, so only record Read or Write, will inevitably miss some packets. The reason that it can't distinguish between Read and Write is that the source process ids for both Read and Write operations are often the same. If pidA_write, pidB_Read. this is clear. But if pidA_write, pidA_Read, you say the data is from A to B, or from B to A. How can it not be from A to A, because this pipe is connected by A and B. This is a very fatal problem. This is a very fatal problem and cannot be solved.

In addition, tracking mojoIPC by intercepting Io enables obtaining real-time mojoIPC information, mainly PlatformHandle, e.g. SharedBuffer, shared memory included in DataPipe. The intercept trace is serialized in all mojoIPC operations now. After all, sniff only captures transient residual images. platformHandle constantly DuplicateHandle and close immediately after the handling process. By the time you analyze the sniff data, all PlatformHandles may have been transformed and reused. If you need to accurately capture the contents of all SharedBuffer or DataPipe traffic, there seems to be no choice but to intercept the Io. I'll analyze how far sniff can go with examples later when I explain sniff mojoIPC capturing https.

Have to spit out a bit, python because of GIL, multi-threading has become enough not (chicken) give (rib) power. Originally, ctypes were used instead of JIT-C for convenience. But when used in patch code, especially multi-threaded, it's really a big pit. Performance not to mention, deadlock is only angry. cpython GIL everywhere. python suitable for multi-process than multi-threaded. If you're just executing python scripts, it's probably not a big problem because it's still within the system closure. As soon as ctypes is used to make calls across language boundaries and multiple threads use ctypes concurrently and in parallel, the problem starts in a big way. Even if you call DebugLogStr with ctypes to print a fixed content with only two threads concurrently, it will deadlock. I used to instantly fall (servant) on my face (street) when patching dense IO thread pooling code. I had to migrate back to c/c++ code again. After all, python has too many wheels to turn, and if the problem wasn't so big that deadlocks wouldn't work, I'd still put up with the runtime efficiency. Luckily I also developed JIT-C similar functionality.

The following demo generates execution code to patch the Iocp and track mojo data through my JustInTimeC.

The following diagram demonstrates that the tracked data will be analyzed.

The demo below takes the tracked data, writes it to WireShark, and lets WireShark's lua script analyze it.

 

How to sniff mojoIPC and grab HTTPS via sniff mojoIPC.

Intercepting https requests, shared onlineWeChat PC-based small program packet capture method.By building a proxy server, by proxy server Burp to do the trick, man-in-the-middle attacks (MITM) or SSL splitting, etc. of other similar tools.

Now back to my present post, and not using the http(s) proxy tool, chrominum exists another stream path. On top of the https communication, there is a layer of mojom services. These services take the user's URL request, turn it into a web request, and take the web response data and notify the user through the service. So I can bypass the network and just sniff into plaintext requests, plaintext data. Right.

If it's just sniff requests, it's fine via mojo. Once you understand the architecture of chrome, you can realize that network is also a sub-service that has to have a host to run. Just like COM has to have a dllhost process. Isn't it ok to intercept https requests just by sniffing to the network service's mojo? All URL requests call the network service via the () method. the URL response is notified by. The response will generally use DataPipe for data delivery, so sniff mojoIPC can't do anything to get the response content. This is consistent with the CEF processing flow. In CEF, CefClient's CefRequestHandler triggers Browser's CefRequesthandler when the Renderer needs to load href or url requests when processing scripts.Similarly, in chrominum, the Renderer requests Browser to process the URL request, if the scheme needs a network request, Browser will pass it to the network service to handle it, otherwise it will handle it by itself, and Browser will pass the response result to Renderer.

Now I show you how.

"": {
    "definition": "struct URLRequest { string method;  url; SiteForCookies site_for_cookies; bool update_first_party_url_on_redirect; ? request_initiator; array<> navigation_redirect_chain; ? isolated_world_origin;  referrer; URLRequestReferrerPolicy referrer_policy; HttpRequestHeaders headers; HttpRequestHeaders cors_exempt_headers; int32 load_flags; int32 resource_type; RequestPriority priority; CorsPreflightPolicy cors_preflight_policy; bool originated_from_service_worker; bool skip_service_worker; bool corb_detachable = false; RequestMode mode; CredentialsMode credentials_mode; RedirectMode redirect_mode; string fetch_integrity; RequestDestination destination; URLRequestBody? request_body; bool keepalive; bool has_user_gesture; bool enable_load_timing; bool enable_upload_progress; bool do_not_prompt_for_login; bool is_outermost_main_frame; int32 transition_type; int32 previews_state; bool upgrade_if_insecure; bool is_revalidating; mojo_base.? throttling_profile_id; mojo_base.? fetch_window_id; string? devtools_request_id; string? devtools_stack_id; bool is_fetch_like_api; bool is_favicon; RequestDestination original_destination; TrustedUrlRequestParams? trusted_params; mojo_base.? recursive_prefetch_token; TrustTokenParams? trust_token_params; WebBundleTokenParams? web_bundle_token_params; array<SourceType>? devtools_accepted_stream_types; NetLogSource? net_log_create_info; NetLogSource? net_log_reference_info; IPAddressSpace target_ip_address_space;};",
"": {
    "definition": "CreateLoaderAndStart(pending_receiver<URLLoader> loader, int32 request_id, uint32 options, URLRequest request, pending_remote<URLLoaderClient> client, MutableNetworkTrafficAnnotationTag traffic_annotation);",
"": {
    "definition": "OnReceiveResponse(URLResponseHead head, handle<data_pipe_consumer>? body, mojo_base.? cached_metadata);",

(), accepts the parameter URLRequest and remote<URLLoaderClient>. URLRequest can be analyzed and URLLoaderClient is used for asynchronous callback to transfer the response data. The body of the response data is used as a carrier with DataPipeConsumer.

Below is a () packet grab, with parameters analyzed. xweb_xhr, URL, header-fields, URL-argurments, Cookies.

Now I will, again, upgrade to support. Grab Bag(). Grabbing js, json data, PNG files, video streams, etc.

 

From wireshark, it's easy to see that more than half of the DataPipes are not successfully sniffing out. The OnReceiveResponse(...) that I filtered out above, means there is a DataPipe. [+1 native handle], which means there is a DataPipe. the ones that I was able to successfully sniff out, I generated a new packet RawBuffer with their contents. the reason for the sniff failures is because the serialization of the DataPipeDispatcher also includes the serialization of a handle to sharedMemory, and I I have to DuplicateHandle this handle to read the contents every time I monitor the write control. But mojo is also DuplicateHandleing and closing the source handle at the same time. That's a race to the bottom. But this DuplicateHandle, mojo is doing very frequently. It's fine if it's only a couple of times a second, but in reality it's dozens and dozens of times a hundred.

The following figure shows the DuplicateHandle count statistics for the WeChatAppEx--type=Browser process.

During the development process, we found that MergePort can establish a MessagePipe connection between two nodes other than itself.The DataPipeConsumer can also be forwarded to other nodes by the intermediary.Imagine there is such a data flow, A->me->B. If me just forwards the data, and the two nodes are DataPipe is used for data transfer, then it is much more efficient for me to pass the DataPipeConsumer to B for use.

The following figure shows that Utility --type=network originally sends network data to Browser, which forwards it to Render-4. Instead, Browser will hold hands with Render-4 for Utility and give DataPipeConsumer to Render-4, after which Utility will directly associate with Render-4.

 

 

How to open devtools for small programs.

github has the open source project WeChatOpenDevTools. the principle is, intercept the call CreateProcessW, append the command line option --enable-xweb-inspect. intercept WeChatAppEx start applet function entry, modify the Json option, add enable_vconsole:true. still modify WeChatAppEx a menu item related string to DevTools. to deploy new things is too much trouble. vconsole:true. still modify the string associated with one of the WeChatAppEx menu items to DevTools. it was too much of a hassle to deploy something new, and after substituting all the processes with WinDbg, it turned out to work. Then in reverse analysis, I found that these are controlled by the WeChat process configuration. enable-xweb-inspect is controlled by a global json in wmpf_host_export.dll, and vconsole is controlled by a property of AppletPkgDownLoadMgr. By modifying these two things, vconsole can be opened without any problem, and no need to change the menu item strings and other weird stuff. mini-program, the name is a bit chinglish, and it seems that they don't use mini-program in their code naming. applet is its real name. Any Game and Applet-related classes, services, functions, etc., are basically related to the small program. Even Public is using WMPF, but there's no vconsole available. In any case, vconsole is a feature made by the family for people to use, and what we're doing is just tuning it to use it, which shouldn't violate anything.

Wmpf is a complete Chrome. implement the Browser process as one of its sub-service processes, XPlugin WMPF is to start Wmpf's Browser process through the MojoEmbedder of wmpf_host_export.dll and establish the Ipc relationship. weChat as WmpfHost role. how Browser opens the applet, understand the process of interaction, it is clear who controls the vconsole. when Browser's applet icon is clicked, the onclick event is in Render to process the js script, which is needed to open the applet, it calls Browser's service, which calls WeChat's body as the WmpfHost's service. This makes it quite obvious that it is WeChat that controls the permissions of the vconsole.

Below is the 85xx version of the WMPF-Applet with vconsole and no devtool

Below is the 112xx version of WMPF-Applet, which not only has vconsole, but also has devtool. you can only see the request url, but not the return data, and the header fields related to the request. But the Applet's DevTool is still neutered and limited.

Below is the WMPF homepage, which has the most complete DevTool, but only allows debugging of the homepage.

 

That's it for this post, see you in the next one.

 

Reverse WeChat (six, grab the applet https by sniffing mojo, open the applet devtool)

Reverse WeChat (v, mmmojo, wmpfmojo)

Reverse TDX x Reverse WeChat x Reverse Qt (fun reversal, signal-slot usage you haven't seen before)

Reverse WeChat (IV, mars, web module)

Reverse WeChat (three, EventCenter, event center for all functional modules)

Reverse WeChat (II, WeUIEngine, UI Engine)

Reverse wechat (I, plan to warm up)

I have more.Reverse Calligraphy Series

I have another one.The K-Line Technical Tools Program KTL.You can develop formulas, QT, data analysis, etc. in C++14.