本文为看雪论坛精华文章
看雪论坛作者ID:橘喵Cat
一
前言
二
初步环境准备
三
找到js资源文件所在
四
解密资源文件
///
// All ref-counted framework structures must include this structure first.
///
typedef struct _cef_base_ref_counted_t {
///
// Size of the data structure.
///
size_t size;
///
// Called to increment the reference count for the object. Should be called
// for every new copy of a pointer to a given object.
///
void(CEF_CALLBACK* add_ref)(struct _cef_base_ref_counted_t* self);
///
// Called to decrement the reference count for the object. If the reference
// count falls to 0 the object should self-delete. Returns true (1) if the
// resulting reference count is 0.
///
int(CEF_CALLBACK* release)(struct _cef_base_ref_counted_t* self);
///
// Returns true (1) if the current reference count is 1.
///
int(CEF_CALLBACK* has_one_ref)(struct _cef_base_ref_counted_t* self);
///
// Returns true (1) if the current reference count is at least 1.
///
int(CEF_CALLBACK* has_at_least_one_ref)(struct _cef_base_ref_counted_t* self);
} cef_base_ref_counted_t;
///
// Structure that supports the reading of zip archives via the zlib unzip API.
// The functions of this structure should only be called on the thread that
// creates the object.
///
typedef struct _cef_zip_reader_t {
///
// Base structure.
///
cef_base_ref_counted_t base;
///
// Moves the cursor to the first file in the archive. Returns true (1) if the
// cursor position was set successfully.
///
int(CEF_CALLBACK* move_to_first_file)(struct _cef_zip_reader_t* self);
///
// Moves the cursor to the next file in the archive. Returns true (1) if the
// cursor position was set successfully.
///
int(CEF_CALLBACK* move_to_next_file)(struct _cef_zip_reader_t* self);
///
// Moves the cursor to the specified file in the archive. If |caseSensitive|
// is true (1) then the search will be case sensitive. Returns true (1) if the
// cursor position was set successfully.
///
int(CEF_CALLBACK* move_to_file)(struct _cef_zip_reader_t* self,
const cef_string_t* fileName,
int caseSensitive);
///
// Closes the archive. This should be called directly to ensure that cleanup
// occurs on the correct thread.
///
int(CEF_CALLBACK* close)(struct _cef_zip_reader_t* self);
// The below functions act on the file at the current cursor position.
///
// Returns the name of the file.
///
// The resulting string must be freed by calling cef_string_userfree_free().
cef_string_userfree_t(CEF_CALLBACK* get_file_name)(
struct _cef_zip_reader_t* self);
///
// Returns the uncompressed size of the file.
///
int64(CEF_CALLBACK* get_file_size)(struct _cef_zip_reader_t* self);
///
// Returns the last modified timestamp for the file.
///
cef_basetime_t(CEF_CALLBACK* get_file_last_modified)(
struct _cef_zip_reader_t* self);
///
// Opens the file for reading of uncompressed data. A read password may
// optionally be specified.
///
int(CEF_CALLBACK* open_file)(struct _cef_zip_reader_t* self,
const cef_string_t* password);
///
// Closes the file.
///
int(CEF_CALLBACK* close_file)(struct _cef_zip_reader_t* self);
///
// Read uncompressed file contents into the specified buffer. Returns < 0 if
// an error occurred, 0 if at the end of file, or the number of bytes read.
///
int(CEF_CALLBACK* read_file)(struct _cef_zip_reader_t* self,
void* buffer,
size_t bufferSize);
///
// Returns the current offset in the uncompressed file contents.
///
int64(CEF_CALLBACK* tell)(struct _cef_zip_reader_t* self);
///
// Returns true (1) if at end of the file contents.
///
int(CEF_CALLBACK* eof)(struct _cef_zip_reader_t* self);
} cef_zip_reader_t;
///
// Writes the contents of |src_dir| into a zip archive at |dest_file|. If
// |include_hidden_files| is true (1) files starting with "." will be included.
// Returns true (1) on success. Calling this function on the browser process UI
// or IO threads is not allowed.
///
CEF_EXPORT int cef_zip_directory(const cef_string_t* src_dir,
const cef_string_t* dest_file,
int include_hidden_files);
///
// Create a new cef_zip_reader_t object. The returned object's functions can
// only be called from the thread that created the object.
///
CEF_EXPORT cef_zip_reader_t* cef_zip_reader_create(
struct _cef_stream_reader_t* stream);
五
开启CEF框架调试功能
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include "detours/detours.h"
#include "include/capi/cef_browser_capi.h"
#include "include/internal/cef_types_win.h"
#include "include/capi/cef_client_capi.h"
#include "include/internal/cef_win.h"
#include <Windows.h>
PVOID g_cef_browser_host_create_browser = nullptr;
PVOID g_cef_get_keyboard_handler = NULL;
PVOID g_cef_on_key_event = NULL;
void SetAsPopup(cef_window_info_t* window_info) {
window_info->style =
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE;
window_info->parent_window = NULL;
window_info->x = CW_USEDEFAULT;
window_info->y = CW_USEDEFAULT;
window_info->width = CW_USEDEFAULT;
window_info->height = CW_USEDEFAULT;
}
int CEF_CALLBACK hook_cef_on_key_event(
struct _cef_keyboard_handler_t* self,
struct _cef_browser_t* browser,
const struct _cef_key_event_t* event,
cef_event_handle_t os_event) {
OutputDebugStringA("[detours] hook_cef_on_key_event \n");
auto cef_browser_host = browser->get_host(browser);
// 键盘按下且是F12
if (event->type == KEYEVENT_RAWKEYDOWN && event->windows_key_code == 123) {
cef_window_info_t windowInfo{};
cef_browser_settings_t settings{};
cef_point_t point{};
SetAsPopup(&windowInfo);
OutputDebugStringA("[detours] show_dev_tools \n");
// 开启调试窗口
cef_browser_host->show_dev_tools
(cef_browser_host, &windowInfo, 0, &settings, &point);
}
return reinterpret_cast<decltype(&hook_cef_on_key_event)>
(g_cef_on_key_event)(self, browser, event, os_event);
}
struct _cef_keyboard_handler_t* CEF_CALLBACK hook_cef_get_keyboard_handler(
struct _cef_client_t* self) {
OutputDebugStringA("[detours] hook_cef_get_keyboard_handler \n");
// 调用原始的修改get_keyboard_handler函数
auto keyboard_handler = reinterpret_cast<decltype(&hook_cef_get_keyboard_handler)>
(g_cef_get_keyboard_handler)(self);
if (keyboard_handler) {
// 记录原始的按键事件回调函数
g_cef_on_key_event = keyboard_handler->on_key_event;
// 修改返回值中的按键事件回调函数
keyboard_handler->on_key_event = hook_cef_on_key_event;
}
return keyboard_handler;
}
int hook_cef_browser_host_create_browser(
const cef_window_info_t* windowInfo,
struct _cef_client_t* client,
const cef_string_t* url,
const struct _cef_browser_settings_t* settings,
struct _cef_dictionary_value_t* extra_info,
struct _cef_request_context_t* request_context) {
OutputDebugStringA("[detours] hook_cef_browser_host_create_browser \n");
// 记录原始的get_keyboard_handler
g_cef_get_keyboard_handler = client->get_keyboard_handler;
// 修改get_keyboard_handler
client->get_keyboard_handler = hook_cef_get_keyboard_handler;
return reinterpret_cast<decltype(&hook_cef_browser_host_create_browser)>
(g_cef_browser_host_create_browser)(
windowInfo, client, url, settings, extra_info, request_context);
}
// Hook cef_browser_host_create_browser
BOOL APIENTRY InstallHook()
{
OutputDebugStringA("[detours] InstallHook \n");
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
g_cef_browser_host_create_browser =
DetourFindFunction("libcef.dll", "cef_browser_host_create_browser");
DetourAttach(&g_cef_browser_host_create_browser,
hook_cef_browser_host_create_browser);
LONG ret = DetourTransactionCommit();
return ret == NO_ERROR;
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
InstallHook();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
六
尝试做点什么功能+总结(未遂)
看雪ID:橘喵Cat
https://bbs.pediy.com/user-home-940656.htm
2.5折门票限时抢购
峰会官网:https://meet.kanxue.com/kxmeet-6.htm
# 往期推荐
球分享
球点赞
球在看
点击“阅读原文”,了解更多!