diff --git a/README.md b/README.md index 2e3c4a0..b44c371 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -# 简介 +# Introduction -jshook是对应用程序注入frida,你只需要会js就可以快速实现hook,并且支持java层和native层,降低开发人员的技术门槛,简化hook流程。 +jshook is to inject Frida into the application. You only need to know JS to quickly implement the hook. It supports Java layer and native layer, lowering the technical threshold for developers and simplifying the hook process. diff --git a/api/md0.md b/api/md0.md index dfd2bc6..ec8af48 100644 --- a/api/md0.md +++ b/api/md0.md @@ -1,42 +1,42 @@ # global -简易调用的全局函数 +Global function for easy calling ## toast(message) -`参数`: +`parameters`: `message`: string ## alert(message) -`参数`: +`parameters`: `message`: string ## confirm(message,callback) -`参数`: +`parameters`: `message`: string `callback`: function -示例: +Example: ```javascript confirm('is ok?', { - ok: function () { - //... - }, - cancel: function () { - //... - } +ok: function () { +//... +}, +cancel: function () { +//... +} }) ``` ## uuid() -返回32位小写uuid +Returns 32-bit lowercase uuid -`返回值`: string +`return value`: string diff --git a/api/md1.md b/api/md1.md index c0cc309..9cd3151 100644 --- a/api/md1.md +++ b/api/md1.md @@ -1,43 +1,43 @@ # runtime -用于获取当前hook运行时相关基础信息 +Used to obtain basic information related to the current hook runtime ## runtime.appInfo -`返回值`: ApplicationInfo +`Return value`: ApplicationInfo ## runtime.packageName -`返回值`: string +`Return value`: string ## runtime.processName -`返回值`: string +`Return value`: string ## runtime.classLoader -`返回值`: ClassLoader +`Return value`: ClassLoader ## runtime.isKernel -是否在内核模式中 +Is it in kernel mode? -`返回值`: boolean +`Return value`: boolean ## runtime.coreVersionCode -获取当前jshook的版本号 +Get the current jshook version number -`返回值`: int +`Return value`: int ## runtime.modVersion -获取当前firamod的版本 +Get the current firamod version -`返回值`: string +`Return value`: string ## runtime.modVersionCode -获取当前firamod的版本号 +Get the current firamod version number -`返回值`: int +`Return value`: int diff --git a/api/md10.md b/api/md10.md index 8072926..612bf3a 100644 --- a/api/md10.md +++ b/api/md10.md @@ -1,10 +1,10 @@ # modmenu -这是一个mod菜单,可以定制简单的菜单悬浮窗,也可以用于绘制,该接口使用imgui实现,可以创建多个悬浮窗实例 +This is a mod menu that can customize a simple menu floating window and can also be used for drawing. This interface is implemented using imgui and can create multiple floating window instances ## modmenu.create(title,options,function) -`参数`: +`Parameters`: `title`: string @@ -12,182 +12,182 @@ `function`: function -`返回值`: 实例 +`Return value`: Example -示例: +Example: ```javascript modmenu.create('test mod', [ - { - 'type': 'text', - 'val': 'text content...', - 'size': 60, - 'color': '#FF0000' - }, - { - 'type': 'select', - 'item': [ - 'test', - 'test2', - 'test3' - ], - 'val': 1 - }, - { - 'type': 'category', - 'title': 'category title' - }, - { - 'type': 'switch', - 'title': 'switch1 title', - 'val': true - }, - { - 'type': 'switch', - 'title': 'switch2 title' - }, - { - 'type': 'button', - 'title': 'button title' - }, - { - 'type': 'input', - 'title': 'input title', - 'val': 'default value' - }, - { - 'type': 'collapse', - 'title': 'collapse title', - 'item': [ - { - 'type': 'switch', - 'title': 'switch title' - } - ], - 'default': true - }, - { - 'type': 'slider', - 'title': 'slider title', - 'val': 88, - 'min': 1, - 'max': 100 - }, - { - 'type': 'checkbox', - 'title': 'checkbox title', - 'val': true - }, - { - 'type': 'radio', - 'title': 'radio title', - 'item': [ - 'test', - 'test2', - 'test3' - ], - 'val': 0 - }, - { - 'type': 'image', - 'width': 60, - 'height': 60, - 'val': 'https://jsonet.cdnipcs.com/test.jpg' - } +{ +'type': 'text', +'val': 'text content...', +'size': 60, +'color': '#FF0000' +}, +{ +'type': 'select', +'item': [ +'test', +'test2', +'test3' +], +'val': 1 +}, +{ +'type': 'category', +'title': 'category title' +}, +{ +'type': 'switch', +'title': 'switch1 title', +'val': true +}, +{ +'type': 'switch', +'title': 'switch2 title' +}, +{ +'type': 'button', +'title': 'button title' +}, +{ +'type': 'input', +'title': 'input title', +'val': 'default value' +}, +{ +'type': 'collapse', +'title': 'collapse title', +'item': [ +{ +'type': 'switch', +'title': 'switch title' +} +], +'default': true +}, +{ +'type': 'slider', +'title': 'slider title', +'val': 88, +'min': 1, +'max': 100 +}, +{ +'type': 'checkbox', +'title': 'checkbox title', +'val': true +}, +{ +'type': 'radio', +'title': 'radio title', +'item': [ +'test', +'test2', +'test3' +], +'val': 0 +}, +{ +'type': 'image', +'width': 60, +'height': 60, +'val': 'https://jsonet.cdnipcs.com/test.jpg' +} ] , { - onchange: function (result) { - console.log(JSON.stringify(result)); - switch(result.id) { - case '1': - console.log('ok'); - break; - } - } +onchange: function (result) { +console.log(JSON.stringify(result)); +switch(result.id) { +case '1': +console.log('ok'); +break; +} +} }) ``` -## 自定义控件id +## Custom control id -你可以给每个控件自定义id,id不能重复,例如按钮的参数 +You can customize the id for each control. The id cannot be repeated, such as the parameters of a button ```javascript { - 'id': 'test', - 'type': 'button', - 'title': 'button title' +'id': 'test', +'type': 'button', +'title': 'button title' } ``` -## 多个tab实例 +## Multiple tab instances ```javascript modmenu.create('test2', [ - { - 'type': 'tab', - 'item': [ - { - 'title': 'tab1', - 'item': [ - { - 'type': 'text', - 'val': 'tab1' - } - ] - }, - { - 'title': 'tab2', - 'item': [ - { - 'type': 'text', - 'val': 'tab2' - } - ] - } - ], - 'default': 1 - } +{ +'type': 'tab', +'item': [ +{ +'title': 'tab1', +'item': [ +{ +'type': 'text', +'val': 'tab1' +} +] +}, +{ +'title': 'tab2', +'item': [ +{ +'type': 'text', +'val': 'tab2' +} +] +} +], +'default': 1 +} ], { - onchange: function (result) { - console.log(JSON.stringify(result)) - } +onchange: function (result) { +console.log(JSON.stringify(result)) +} }) ``` -## [实例].close() +## [Instance].close() -示例: +Example: ```javascript var menu1 = modmenu.create('test mod', [], { - onchange: function (result) { - } +onchange: function (result) { +} }); setTimeout(function () { - menu1.close(); +menu1.close(); }, 2000); ``` -## [实例].state() +## [Instance].state() -显示悬浮窗底部状态栏,imgui相关的信息 +Display the status bar at the bottom of the floating window, imgui related information -## [实例].size(width,height) +## [Instance].size(width,height) -调整悬浮窗大小,px值 +Adjust the size of the floating window, px value -`参数`: +`Parameter`: `width`: int `height`: int -## [实例].position(type,x,y) +## [Instance].position(type,x,y) -设置悬浮窗默认位置,type为1到9对应9个默认位置,x和y是px值 +Set the default position of the floating window. Type is 1 to 9, corresponding to 9 default positions. x and y are px values -`参数`: +`Parameters`: `type`: int @@ -195,27 +195,27 @@ setTimeout(function () { `y`: int -## [实例].icon(img) +## [Instance].icon(img) -设置悬浮窗图标图片,img为图片base64字符串或者是图片url地址 +Set the floating window icon image. img is a base64 string or an image URL address -`参数`: +`Parameters`: `img`: string -## [实例].edgeHiden(enable) +## [Instance].edgeHiden(enable) -icon图标拖动到屏幕边缘自动隐藏,默认不开启 +The icon is automatically hidden when dragged to the edge of the screen. It is not enabled by default -`参数`: +`Parameters`: `enable`: boolean -## [实例].update(id,value) +## [Instance].update(id,value) -动态更改菜单控件的值 +Dynamically change the value of the menu control -`参数`: +`Parameters`: `id`: string @@ -223,4 +223,4 @@ icon图标拖动到屏幕边缘自动隐藏,默认不开启 ## modmenu.closeAll() -关闭所有创建的mod菜单 +Close all created mod menus diff --git a/api/md11.md b/api/md11.md index 72a0aaf..463806d 100644 --- a/api/md11.md +++ b/api/md11.md @@ -1,18 +1,18 @@ # storage -用于本地数据的存储,数据存在被hook的应用私有路径中, +Used for local data storage, the data is stored in the private path of the hooked application, ## storage.get(key) -`参数`: +`Parameters`: `key`: string -`返回值`: string +`Return value`: string ## storage.set(key,data) -`参数`: +`Parameters`: `key`: string @@ -20,7 +20,7 @@ ## storage.del(key) -`参数`: +`Parameters`: `key`: string diff --git a/api/md12.md b/api/md12.md index 2df4d54..297e835 100644 --- a/api/md12.md +++ b/api/md12.md @@ -1,99 +1,99 @@ # convert -用于常用的转换 +Used for common conversions ## convert.stringToByte(data) -`参数`: +`Parameters`: `data`: string -`返回值`: byte[] +`Return value`: byte[] ## convert.byteToString(data) -`参数`: +`Parameters`: `data`: byte[] -`返回值`: string +`Return value`: string ## convert.hexStringToByte(data) -`参数`: +`Parameters`: `data`: string -`返回值`: byte[] +`Return value`: byte[] ## convert.byteToHexString(data) -`参数`: +`Parameters`: `data`: byte[] -`返回值`: string +`Return value`: string ## convert.byteToBitmap(data) -`参数`: +`Parameters`: `data`: byte[] -`返回值`: Bitmap +`Return value`: Bitmap ## convert.bitmapToByte(data) -`参数`: +`Parameters`: `data`: Bitmap -`返回值`: byte[] +`Return value`: byte[] ## convert.byteToDrawable(data) -`参数`: +`Parameters`: `data`: byte[] -`返回值`: Drawable +`Return`: Drawable ## convert.drawableToByte(data) -`参数`: +`Parameters`: `data`: Drawable -`返回值`: byte[] +`Return`: byte[] ## convert.byteToInputStream(data) -`参数`: +`Parameters`: `data`: byte[] -`返回值`: InputStream +`Return`: InputStream ## convert.inputStreamToByte(data) -`参数`: +`Parameters`: `data`: InputStream -`返回值`: byte[] +`Return`: byte[] ## convert.byteToOutputStream(data) -`参数`: +`Parameters`: `data`: byte[] -`返回值`: OutputStream +`Return`: OutputStream ## convert.outputStreamToByte(data) -`参数`: +`Parameters`: `data`: OutputStream -`返回值`: byte[] +`Return`: byte[] diff --git a/api/md13.md b/api/md13.md index 788f779..9f14904 100644 --- a/api/md13.md +++ b/api/md13.md @@ -1,10 +1,10 @@ # dialog -常用的对话框 +Common dialog boxes ## dialog.input(title,callback,content) -`参数`: +`Parameters`: `title`: string @@ -12,13 +12,13 @@ `content`: string -示例: +Example: ```javascript -dialog.input('标题', { - ok: function (res) { - console.log(res); - }, - cancel: function () { } -}, '默认值'); +dialog.input('title', { +ok: function (res) { +console.log(res); +}, +cancel: function () { } +}, 'default value'); ``` diff --git a/api/md14.md b/api/md14.md index 176529a..f340a26 100644 --- a/api/md14.md +++ b/api/md14.md @@ -1,68 +1,68 @@ # view -视图层操作 +View layer operation ## view.findViewByText(text) -查找当前activity所有包含字符的TextView +Find all TextViews containing characters in the current activity -`参数`: +`Parameters`: `text`: string -`返回值`: List\ +`Return value`: List\ -示例: +Example: ```javascript var time1 = setInterval(function () { - var view1 = view.findViewByText('Text'); - if (view1.size() > 0) { - clearInterval(time1); - view1.get(0).setText('fuck'); - var p = view.getPosition(view1.get(0)); - keys.click(p.get(0), p.get(1)); - setTimeout(function () { - keys.back(); - }, 2000); - } +var view1 = view.findViewByText('Text'); +if (view1.size() > 0) { +clearInterval(time1); +view1.get(0).setText('fuck'); +var p = view.getPosition(view1.get(0)); +keys.click(p.get(0), p.get(1)); +setTimeout(function () { +keys.back(); +}, 2000); +} }, 100); ``` ## view.getPosition(view) -获取view的位置 +Get the position of the view -`参数`: +`Parameters`: `view`: View -`返回值`: List\ +`Return value`: List\ ## view.findViewPositionByText(text) -通过查找所有包含字符的TextView的位置 +By finding the position of all TextViews containing characters -`参数`: +`Parameters`: `text`: string -`返回值`: List\\> +`Return value`: List\\> ## view.runOnUiThread(function) -在ui线程中执行 +Execute in the ui thread -`参数`: +`Parameters`: `function`: function -示例: +Example: ```javascript view.runOnUiThread({ - run: function () { - //... - } +run: function () { +//... +} }); ``` diff --git a/api/md15.md b/api/md15.md index 42d8574..aa34392 100644 --- a/api/md15.md +++ b/api/md15.md @@ -1,12 +1,12 @@ # keys -模拟按键操作,需要安装Magisk模块才可以调用 +Simulate key operation, you need to install Magisk module to call ## keys.click(x,y) -模拟点击x,y位置 +Simulate clicking x,y position -`参数`: +`Parameters`: `x`: int @@ -14,9 +14,9 @@ ## keys.swipe(x,y,tox,toy,time) -模拟滑动,从x,y位置滑动到tox,toy位置,time持续时间 +Simulate sliding, sliding from x,y position to tox,toy position, time duration -`参数`: +`Parameters`: `x`: int @@ -30,21 +30,20 @@ ## keys.back() -返回上一页 +Return to the previous page ## keys.home() -返回首页 +Return to the home page ## keys.enter() -回车 +Enter ## keys.del() -删除 +Delete ## keys.text(text) -模拟输入文本,请注意调用这个需要确定处于文本输入焦点状态 - +Simulate text input, please note that you need to make sure that the text input focus is in the call diff --git a/api/md16.md b/api/md16.md index ca74790..6d3d082 100644 --- a/api/md16.md +++ b/api/md16.md @@ -1,93 +1,93 @@ # colors -用于颜色字符串与数值的转换 +Used for color string and numerical conversion ## colors.toString(color) -返回颜色值的字符串,格式为 "#AARRGGBB" +Returns the color value string, in the format of "#AARRGGBB" -`参数`: +`Parameters`: -`color`: int rgb颜色值 +`color`: int rgb color value -`返回值`: string +`Return value`: string ## colors.red(color) -返回颜色color的R通道的值,范围0 ~ 255 +Returns the value of the R channel of color color, ranging from 0 to 255 -`参数`: +`Parameters`: -`color`: string 字符串颜色值 +`color`: string string color value -`返回值`: int +`Return value`: int ## colors.green(color) -返回颜色color的G通道的值,范围0 ~ 255 +Returns the value of the G channel of color color, ranging from 0 to 255 -`参数`: +`Parameters`: -`color`: string 字符串颜色值 +`color`: string string color value -`返回值`: int +`Return value`: int ## colors.blue(color) -返回颜色color的B通道的值,范围0 ~ 255 +Returns the value of the B channel of color color, ranging from 0 to 255 -`参数`: +`Parameters`: -`color`: string 字符串颜色值 +`color`: string string color value -`返回值`: int +`Return value`: int ## colors.alpha(color) -返回颜色color的Alpha通道的值,范围0 ~ 255 +Returns the value of the alpha channel of color color, ranging from 0 to 255 -`参数`: +`Parameters`: -`color`: string 字符串颜色值 +`color`: string string color value -`返回值`: int +`Return value`: int ## colors.rgb(red,green,blue) -返回这些颜色通道构成的整数颜色值 +Returns the integer color value composed of these color channels -`参数`: +`Parameters`: -`red`: int 颜色的R通道的值 +`red`: int color R channel value -`green`: int 颜色的R通道的值 +`green`: int color R channel value -`blue`: int 颜色的R通道的值 +`blue`: int color R channel value -`返回值`: int +`Return value`: int ## colors.argb(alpha,red,green,blue) -返回这些颜色通道构成的整数颜色值 +Returns the integer color value composed of these color channels -`参数`: +`Parameters`: -`alpha`: int 颜色的Alpha通道的值 +`alpha`: int color Alpha channel value -`red`: int 颜色的R通道的值 +`red`: int color R channel value -`green`: int 颜色的R通道的值 +`green`: int color R channel value -`blue`: int 颜色的R通道的值 +`blue`: int color R channel value -`返回值`: int +`Return value`: int ## colors.parseColor(color) -返回这些颜色通道构成的整数颜色值 +Returns the integer color value composed of these color channels -`参数`: +`Parameters`: -`color`: string 字符串颜色值 +`color`: string string color value -`返回值`: int +`Return value`: int diff --git a/api/md17.md b/api/md17.md index 4777449..be1b493 100644 --- a/api/md17.md +++ b/api/md17.md @@ -1,16 +1,16 @@ # moddraw -用于底层绘制,该接口使用imgui实现,可以创建多个绘制实例 +Used for underlying drawing, this interface is implemented using imgui, and multiple drawing instances can be created ## moddraw.create(function) -`参数`: +`Parameters`: `function`: function -`返回值`: 实例 +`Return value`: Instance -示例: +Example: ```javascript var dw = device.getScreenWidth() @@ -19,101 +19,101 @@ var playerCount = 10 var players = [] const draw1 = moddraw.create({ - draw: function () { - for (var i = 0; i < players.length; i++) { - draw1.line({ - 'start_x': dw / 2, - 'start_y': 0, - 'end_x': players[i][0] + players[i][2] / 2, - 'end_y': players[i][1], - // 'volume': 2, - // 'color': players[i][4], - // 'color_alpha': 0.8 - }) - draw1.rect({ - 'x': players[i][0], - 'y': players[i][1], - 'width': players[i][2], - 'height': players[i][3], - 'border': 2, - 'border_color': '#FF0000', - 'border_color_alpha': 0.8, - 'background': '#000000', - 'background_alpha': 0.8, - 'raduis': 0 - }) - } - draw1.text({ - 'x': 600, - 'y': 800, - 'size': 60, - 'color': '#FFFFFF', - 'color_alpha': 0.8, - 'padding': 10, - 'data': 'test', - 'border': 2, - 'border_color': '#FF0000', - 'border_color_alpha': 0.8, - 'background': '#000000', - 'background_alpha': 0.8, - 'raduis': 10 - }) - draw1.image({ - 'x': 300, - 'y': 800, - 'width': 60, - 'height': 60, - 'data': 'https://jsonet.cdnipcs.com/test.jpg', - 'border': 2, - 'border_color': '#FF0000', - 'border_color_alpha': 0.8, - 'background': '#000000', - 'background_alpha': 0.8, - 'raduis': 10 - }) - } +draw: function () { +for (var i = 0; i < players.length; i++) { +draw1.line({ +'start_x': dw / 2, +'start_y': 0, +'end_x': players[i][0] + players[i][2] / 2, +'end_y': players[i][1], +// 'volume': 2, +// 'color': players[i][4], +// 'color_alpha': 0.8 +}) +draw1.rect({ +'x': players[i][0], +'y': players[i][1], +'width': players[i][2], +'height': players[i][3], +'border': 2, +'border_color': '#FF0000', +'border_color_alpha': 0.8, +'background': '#000000', +'background_alpha': 0.8, +'raduis': 0 +}) +} +draw1.text({ +'x': 600, +'y': 800, +'size': 60, +'color': '#FFFFFF', +'color_alpha': 0.8, +'padding': 10, +'data': 'test', +'border': 2, +'border_color': '#FF0000', +'border_color_alpha': 0.8, +'background': '#000000', +'background_alpha': 0.8, +'raduis': 10 +}) +draw1.image({ +'x': 300, +'y': 800, +'width': 60, +'height': 60, +'data': 'https://jsonet.cdnipcs.com/test.jpg', +'border': 2, +'border_color': '#FF0000', +'border_color_alpha': 0.8, +'background': '#000000', +'background_alpha': 0.8, +'raduis': 10 +}) +} }) function random(min, max) { - return Math.floor(Math.random() * (max - min + 1)) + min +return Math.floor(Math.random() * (max - min + 1)) + min } function playerdata() { - var newPlayers = [] - for (var i = 0; i < playerCount; i++) { - var playerWidth = random(30, 100) - var playerHeight = 2 * playerWidth - var color = random(0, 1) ? "#ff0000" : "#00ff00" - var player = [ - random(0, dw), - random(0, dh), - playerWidth, - playerHeight, - color - ] - newPlayers.push(player) - } - players = newPlayers +var newPlayers = [] +for (var i = 0; i < playerCount; i++) { +var playerWidth = random(30, 100) +var playerHeight = 2 * playerWidth +var color = random(0, 1) ? "#ff0000" : "#00ff00" +var player = [ +random(0, dw), +random(0, dh), +playerWidth, +playerHeight, +color +] +newPlayers.push(player) +} +players = newPlayers } setInterval(function () { - dw = device.getScreenWidth() - dh = device.getScreenHeight() +dw = device.getScreenWidth() +dh = device.getScreenHeight() }, 1000) setInterval(function () { - playerdata() +playerdata() }, 100) ``` -## [实例].close() +## [Instance].close() -关闭绘制 +Close drawing ## moddraw.closeAll() -关闭所有创建的绘制 +Close all created drawings -## 注意事项 +## Notes -- draw回调中只做数据渲染,不要写任何会耗时的代码,把组合绘制数据的逻辑写在外面,draw阻塞会导致渲染效果有延迟 +- Only render data in the draw callback, do not write any time-consuming code, write the logic of combining drawing data outside, draw blocking will cause rendering delay diff --git a/api/md18.md b/api/md18.md index fe4212c..d7c7981 100644 --- a/api/md18.md +++ b/api/md18.md @@ -1,161 +1,161 @@ # kernel -内核模式下使用的接口,需要fridamod框架的支持,通过`runtime.isKernel`判断是否处于内核模式中 +The interface used in kernel mode requires the support of fridamod framework. `runtime.isKernel` is used to determine whether it is in kernel mode -内核模式下,不会注入目标应用,而是克隆出旁观进程,在旁观进程中执行frida,脚本中只能使用jshook提供的api,hook相关api无效 +In kernel mode, the target application will not be injected, but the spectator process will be cloned and frida will be executed in the spectator process. Only the API provided by jshook can be used in the script, and the hook-related API is invalid ## kernel.getModuleBase(libname) -获取某个so共享库的内存地址,可用于内存偏移计算 +Get the memory address of a certain so shared library, which can be used for memory offset calculation -`参数`: +`Parameter`: `libname`: string -`返回值`: string +`Return value`: string ## kernel.readDword(address) -获取内存地址的整数值 +Get the integer value of the memory address -`参数`: +`Parameter`: `address`: string -`返回值`: long +`Return value`: long ## kernel.readFloat(address) -获取内存地址的浮点数值 +Get the floating point value of the memory address -`参数`: +`Parameter`: `address`: string -`返回值`: float +`Return value`: float ## kernel.writeDword(address,value) -内存地址写入整数值 +Write the integer value of the memory address -`参数`: +`Parameter`: `address`: string `value`: long -`返回值`: int +`Return value`: int ## kernel.writeFloat(address,value) -内存地址写入浮点数值 +Write floating point value to memory address -`参数`: +`Parameter`: `address`: string `value`: float -`返回值`: int +`Return value`: int -## 示例脚本 +## Sample script -先下载用于练习的目标应用[https://github.com/JsHookApp/Download/releases/download/files/Learn.Frida.apk](https://github.com/JsHookApp/Download/releases/download/files/Learn.Frida.apk) +First download the target application for practice [https://github.com/JsHookApp/Download/releases/download/files/Learn.Frida.apk](https://github.com/JsHookApp/Download/releases/download/files/Learn.Frida.apk) -以及对应的`dump.cs`文件[https://github.com/JsHookApp/Download/releases/download/files/Learn.Frida_dump.cs](https://github.com/JsHookApp/Download/releases/download/files/Learn.Frida_dump.cs) +And the corresponding `dump.cs` file [https://github.com/JsHookApp/Download/releases/download/files/Learn.Frida_dump.cs](https://github.com/JsHookApp/Download/releases/download/files/Learn.Frida_dump.cs) -`Learn.Frida_dump.cs`文件中主要分析`public class FieldTest : MonoBehaviour`这里的方法 +The `Learn.Frida_dump.cs` file mainly analyzes `public class FieldTest: MonoBehaviour`Method here -以下是脚本示例,脚本中的先通过非内核模式使用frida找到内存基址,当然,你可以使用别的方式找内存基址,然后在内核模式下进行变量值的修改,点击`ShowResult`按钮会出现输入框,用来输入当前`staticA`的值搜索内存地址 +The following is a script example. In the script, frida is used to find the memory base address in non-kernel mode. Of course, you can use other methods to find the memory base address, and then modify the variable value in kernel mode. Click the `ShowResult` button to display an input box for entering the current `staticA` value to search for the memory address ```javascript -//内存扫描 +//Memory scan const memoryScan = (m, pattern, call) => { - Memory.scan(m.base, m.size, pattern, { - onMatch(address, size) { - call(address) - return 'stop'; - }, - onComplete() { - } - }); +Memory.scan(m.base, m.size, pattern, { +onMatch(address, size) { +call(address) +return 'stop'; +}, +onComplete() { +} +}); } function getRandomInt(min, max) { - return Math.floor(Math.random() * (max - min + 1)) + min; +return Math.floor(Math.random() * (max - min + 1)) + min; } -//开始使用内核 +//Start using the kernel if (runtime.isKernel) { - console.log('kernel start') - - const time = setInterval(() => { - const il2cpp = kernel.getModuleBase('libil2cpp.so') - if (il2cpp) { - clearInterval(time) - console.log('il2cpp', il2cpp) - - //读取/修改数据 - setInterval(() => { - const newval = getRandomInt(100, 999) - console.log('newval', newval) - kernel.writeDword('0x7e3fe30c30', newval) - - const kernel_staticA = kernel.readDword('0x7e3fe30c30') - console.log('staticA', kernel_staticA) - }, 3000) - } - }, 100) +console.log('kernel start') + +const time = setInterval(() => { +const il2cpp = kernel.getModuleBase('libil2cpp.so') +if (il2cpp) { +clearInterval(time) +console.log('il2cpp', il2cpp) + +//Read/modify data +setInterval(() => { +const newval = getRandomInt(100, 999) +console.log('newval', newval) +kernel.writeDword('0x7e3fe30c30', newval) + +const kernel_staticA = kernel.readDword('0x7e3fe30c30') +console.log('staticA', kernel_staticA) +}, 3000) +} +}, 100) } else { - //非内核模式下通过frida找到变量的内存基址,你也可以通过其他方法获取 - - const time = setInterval(() => { - const addr = Module.findBaseAddress('libil2cpp.so') - if (addr) { - clearInterval(time) - console.log('libil2cpp ok') - //il2cpp模块地址是动态的 - const il2cpp = ptr(addr) - console.log('il2cpp', il2cpp) - //这个0x667F14是偏移,固定的,指向 ShowResult 方法 - Interceptor.attach(il2cpp.add(0x667F14), { - onEnter: function (args) { - //当前实例 - const instance = args[0] - - //输入当前 staticA 的值去搜索内存 - dialog.input('search_val', { - ok: function (res) { - - //获取搜索范围 - const range = Process.findRangeByAddress(instance) - - //搜索条件 - const pattern = ptr(parseInt(res)).toMatchPattern().replace(' 00 00 00 00', '') - - memoryScan(range, pattern, (address) => { - //变量内存地址 - console.log('staticA_address', address) - - //变量内存值 - const staticA = ptr(address).readInt() - console.log('staticA', staticA) - - //修改 - ptr(address).writeInt(1000) - }) - }, - cancel: function () { - } - }, '') - }, - onLeave: function (retval) { - } - }) - } - }, 100) +//Find the memory base address of the variable through frida in non-kernel mode, you can also get it through other methods + +const time = setInterval(() => { +const addr = Module.findBaseAddress('libil2cpp.so') +if (addr) { +clearInterval(time) +console.log('libil2cpp ok') +//il2cpp module address is dynamic +const il2cpp = ptr(addr) +console.log('il2cpp', il2cpp) +//This 0x667F14 is an offset, fixed, pointing to the ShowResult method +Interceptor.attach(il2cpp.add(0x667F14), { +onEnter: function (args) { +//Current instance +const instance = args[0] + +//Enter the current value of staticA to search memory +dialog.input('search_val', { +ok: function (res) { + +//Get the search range +const range = Process.findRangeByAddress(instance) + +//Search condition +const pattern = ptr(parseInt(res)).toMatchPattern().replace(' 00 00 00 00', '') + +memoryScan(range, pattern, (address) => { +//Variable memory address +console.log('staticA_address', address) + +//Variable memory value +const staticA = ptr(address).readInt() +console.log('staticA', staticA) + +//Modify +ptr(address).writeInt(1000) +}) +}, +cancel: function () { +} +}, '') +}, +onLeave: function (retval) { +} +}) +} +}, 100) } diff --git a/api/md19.md b/api/md19.md index 2163f4b..dfa7000 100644 --- a/api/md19.md +++ b/api/md19.md @@ -1,12 +1,12 @@ # curl -用于进行网络请求,注意,需要被hook的应用拥有网络访问权限,与http接口不同的是,curl属于c++底层请求,而http属于java层请求 +Used to make network requests. Note that the application to be hooked must have network access permissions. Unlike the http interface, curl belongs to the C++ underlying request, while http belongs to the Java layer request -**这个api是fridamod框架专属提供** +**This API is exclusively provided by the fridamod framework** ## curl(url,method,headers,body,function) -`参数`: +`Parameters`: `url`: string @@ -18,16 +18,16 @@ `function`: function -示例: +Example: ```javascript -//get请求 无header 无body +//get request no header no body curl('https://www.baidu.com', 'get', null, null, function (res) { - console.log(res) +console.log(res) }) -//post请求 有header 有body 默认将body转json字符串 application/json方式提交 +//post request with header and body. By default, the body is converted to json string and submitted in application/json mode curl('http://www.baidu.com', 'post', ['test:1'], {test:2}, function (res) { - console.log(res) +console.log(res) }) ``` diff --git a/api/md2.md b/api/md2.md index 90f8361..1e7e0c1 100644 --- a/api/md2.md +++ b/api/md2.md @@ -1,111 +1,111 @@ # app -用于获取当前hook应用的基本信息 +Used to get the basic information of the current hook application ## app.isAppSystem() -判断 App 是否是系统应用 +Determine whether the App is a system application -`返回值`: boolean +`Return value`: boolean ## app.isAppForeground() -判断 App 是否处于前台 +Determine whether the App is in the foreground -`返回值`: boolean +`Return value`: boolean ## app.exitApp() -关闭应用 +Close the application ## app.getAppInfo() -获取 App 信息 +Get App information -`返回值`: object +`Return value`: object ## app.openUrl(url) -打开指定网址 +Open the specified URL -`参数`: +`Parameter`: -`url`: string 网址 +`url`: string URL ## app.startActivity(activity) -启动 Activity +Start Activity -`参数`: +`Parameter`: `activity`: Activity ## app.getActivityList() -获取 Activity 栈链表 +Get the Activity stack list -`返回值`: List +`Return value`: List ## app.finishActivity(activity) -结束 Activity +End Activity -`参数`: +`Parameter`: `activity`: Activity ## app.finishToActivity(activity) -结束到指定 Activity +End to the specified Activity -`参数`: +`Parameters`: `activity`: Activity ## app.startHomeActivity() -回到桌面 +Return to the desktop ## app.dpToPx(value) -dp转px +dp to px -`参数`: +`Parameters`: `value`: float -`返回值`: int +`Return value`: int ## app.pxToDp(value) -px转dp +px to dp -`参数`: +`Parameters`: `value`: float -`返回值`: int +`Return value`: int ## app.getInternalAppDataPath() -获取内存应用数据路径 +Get the internal application data path -`返回值`: string +`Return value`: string ## app.getExternalAppDataPath() -获取外存应用数据路径 +Get the external application data path -`返回值`: string +`Return value`: string ## app.getExternalAppObbPath() -获取外存应用 OBB 路径 +Get the external application OBB path -`返回值`: string +`Return value`: string ## app.getExternalStoragePath() -获取外存路径 +Get the external storage path -`返回值`: string +`Return value`: string diff --git a/api/md20.md b/api/md20.md index ed079f2..3373d82 100644 --- a/api/md20.md +++ b/api/md20.md @@ -1,161 +1,161 @@ # memory -如果你的机型无法输入QX驱动,可以在内核模式下使用这个接口直接读写目标应用内存 +If your model cannot input QX driver, you can use this interface to directly read and write the target application memory in kernel mode ## memory.getModuleBase(libname) -获取某个so共享库的内存地址,可用于内存偏移计算 +Get the memory address of a certain so shared library, which can be used for memory offset calculation -`参数`: +`Parameter`: `libname`: string -`返回值`: string +`Return value`: string ## memory.readDword(address) -获取内存地址的整数值 +Get the integer value of the memory address -`参数`: +`Parameter`: `address`: string -`返回值`: long +`Return value`: long ## memory.readFloat(address) -获取内存地址的浮点数值 +Get the floating point value of the memory address -`参数`: +`Parameter`: `address`: string -`返回值`: float +`Return value`: float ## memory.writeDword(address,value) -内存地址写入整数值 +Write the integer value of the memory address -`参数`: +`Parameter`: `address`: string `value`: long -`返回值`: int +`Return value`: int ## memory.writeFloat(address,value) -内存地址写入浮点数值 +Write floating point value to memory address -`参数`: +`Parameters`: `address`: string `value`: float -`返回值`: int +`Return value`: int -## 示例脚本 +## Sample script -先下载用于练习的目标应用[https://github.com/JsHookApp/Download/releases/download/files/Learn.Frida.apk](https://github.com/JsHookApp/Download/releases/download/files/Learn.Frida.apk) +First download the target application for practice [https://github.com/JsHookApp/Download/releases/download/files/Learn.Frida.apk](https://github.com/JsHookApp/Download/releases/download/files/Learn.Frida.apk) -以及对应的`dump.cs`文件[https://github.com/JsHookApp/Download/releases/download/files/Learn.Frida_dump.cs](https://github.com/JsHookApp/Download/releases/download/files/Learn.Frida_dump.cs) +And the corresponding `dump.cs` file [https://github.com/JsHookApp/Download/releases/download/files/Learn.Frida_dump.cs](https://github.com/JsHookApp/Download/releases/download/files/Learn.Frida_dump.cs) -`Learn.Frida_dump.cs`文件中主要分析`public class FieldTest : MonoBehaviour`这里的方法 +The `Learn.Frida_dump.cs` file mainly analyzes `public class FieldTest: MonoBehaviour`Method here -以下是脚本示例,脚本中的先通过非内核模式使用frida找到内存基址,当然,你可以使用别的方式找内存基址,点击`ShowResult`按钮会出现输入框,用来输入当前`staticA`的值搜索内存地址 +The following is a script example. In the script, frida is used to find the memory base address in non-kernel mode. Of course, you can use other methods to find the memory base address. Click the `ShowResult` button to display an input box for entering the current `staticA` value to search for the memory address ```javascript -//内存扫描 +//Memory scan const memoryScan = (m, pattern, call) => { - Memory.scan(m.base, m.size, pattern, { - onMatch(address, size) { - call(address) - return 'stop'; - }, - onComplete() { - } - }); +Memory.scan(m.base, m.size, pattern, { +onMatch(address, size) { +call(address) +return 'stop'; +}, +onComplete() { +} +}); } function getRandomInt(min, max) { - return Math.floor(Math.random() * (max - min + 1)) + min; +return Math.floor(Math.random() * (max - min + 1)) + min; } -//开始使用内核 +//Start using the kernel if (runtime.isKernel) { - console.log('kernel start') - - const time = setInterval(() => { - const il2cpp = memory.getModuleBase('libil2cpp.so') - if (il2cpp) { - clearInterval(time) - console.log('il2cpp', il2cpp) - - //读取/修改数据 - setInterval(() => { - const newval = getRandomInt(100, 999) - console.log('newval', newval) - memory.writeDword('0x7e3fe30c30', newval) - - const memory_staticA = memory.readDword('0x7e3fe30c30') - console.log('staticA', memory_staticA) - }, 3000) - } - }, 100) +console.log('kernel start') + +const time = setInterval(() => { +const il2cpp = memory.getModuleBase('libil2cpp.so') +if (il2cpp) { +clearInterval(time) +console.log('il2cpp', il2cpp) + +//Read/modify data +setInterval(() => { +const newval = getRandomInt(100, 999) +console.log('newval', newval) +memory.writeDword('0x7e3fe30c30', newval) + +const memory_staticA = memory.readDword('0x7e3fe30c30') +console.log('staticA', memory_staticA) +}, 3000) +} +}, 100) } else { - //非内核模式下通过frida找到变量的内存基址,你也可以通过其他方法获取 - - const time = setInterval(() => { - const addr = Module.findBaseAddress('libil2cpp.so') - if (addr) { - clearInterval(time) - console.log('libil2cpp ok') - //il2cpp模块地址是动态的 - const il2cpp = ptr(addr) - console.log('il2cpp', il2cpp) - //这个0x667F14是偏移,固定的,指向 ShowResult 方法 - Interceptor.attach(il2cpp.add(0x667F14), { - onEnter: function (args) { - //当前实例 - const instance = args[0] - - //输入当前 staticA 的值去搜索内存 - dialog.input('search_val', { - ok: function (res) { - - //获取搜索范围 - const range = Process.findRangeByAddress(instance) - - //搜索条件 - const pattern = ptr(parseInt(res)).toMatchPattern().replace(' 00 00 00 00', '') - - memoryScan(range, pattern, (address) => { - //变量内存地址 - console.log('staticA_address', address) - - Java.perform(function () { - //变量内存值,使用memory接口读取 - const staticA = memory.readDword(String(address)) - console.log('staticA', staticA) - - //修改,使用memory接口修改 - memory.writeDword(String(address), 1000) - }) - }) - }, - cancel: function () { - } - }, '') - }, - onLeave: function (retval) { - } - }) - } - }, 100) +//In non-kernel mode, find the memory base address of the variable through frida, you can also get it through other methods + +const time = setInterval(() => { +const addr = Module.findBaseAddress('libil2cpp.so') +if (addr) { +clearInterval(time) +console.log('libil2cpp ok') +//il2cpp module address is dynamic +const il2cpp = ptr(addr) +console.log('il2cpp', il2cpp) +//This 0x667F14 is an offset, fixed, pointing to the ShowResult method +Interceptor.attach(il2cpp.add(0x667F14), { +onEnter: function (args) { +//Current instance +const instance = args[0] + +//Enter the current value of staticA to search memory +dialog.input('search_val', { +ok: function (res) { + +//Get the search range +const range = Process.findRangeByAddress(instance) + +//Search condition +const pattern = ptr(parseInt(res)).toMatchPattern().replace(' 00 00 00 00', '') + +memoryScan(range, pattern, (address) => { +//Variable memory address +console.log('staticA_address', address) + +Java.perform(function () { +//Variable memory value, read using memory interface +const staticA = memory.readDword(String(address)) +console.log('staticA', staticA) + +//Modify, modify using memory interface +memory.writeDword(String(address), 1000) +}) +}) +}, +cancel: function () { +} +}, '') +}, +onLeave: function (retval) { +} +}) +} +}, 100) } diff --git a/api/md3.md b/api/md3.md index 48a443e..a946583 100644 --- a/api/md3.md +++ b/api/md3.md @@ -1,35 +1,35 @@ # base64 -用于进行字符串base64编码解码 +Used for base64 encoding and decoding of strings ## base64.encode(data) -`参数`: +`Parameters`: `data`: string -`返回值`: string +`Return value`: string ## base64.encodeBytes(data) -`参数`: +`Parameters`: `data`: byte[] -`返回值`: byte[] +`Return value`: byte[] ## base64.decode(data) -`参数`: +`Parameters`: `data`: string -`返回值`: string +`Return value`: string ## base64.decodeBytes(data) -`参数`: +`Parameters`: `data`: byte[] -`返回值`: byte[] +`Return value`: byte[] diff --git a/api/md4.md b/api/md4.md index fada5d5..6c1abf8 100644 --- a/api/md4.md +++ b/api/md4.md @@ -1,37 +1,37 @@ # media -用于播放音乐 +Used to play music ## media.create(data) -`参数`: +`Parameters`: -`data`: url地址或者文件base64值 +`data`: url address or file base64 value -`返回值`: 实例 +`Return value`: instance -调用后默认会自动播放,无需调用start +After calling, it will play automatically by default, no need to call start -## [实例].start() +## [Instance].start() -开始播放 +Start playing -## [实例].pause() +## [Instance].pause() -暂停播放 +Pause playing -## [实例].stop() +## [Instance].stop() -停止播放 +Stop playing -## [实例].loop(state) +## [Instance].loop(state) -`参数`: +`Parameters`: `state`: boolean -是否循环播放,默认音乐只播放一次 +Whether to play in a loop, by default, music is played only once ## media.closeAll() -关闭所有实例 +Close all instances diff --git a/api/md5.md b/api/md5.md index 42970e3..305d865 100644 --- a/api/md5.md +++ b/api/md5.md @@ -1,10 +1,10 @@ # crypto -用于进行字符串加密解密 +Used for string encryption and decryption ## crypto.encrypt(key,data,enctype,transformation) -`参数`: +`Parameters`: `key`: string @@ -12,13 +12,13 @@ `enctype`: CRYPTO_AES | CRYPTO_DES -`transformation`: 转换的名称 例如 `DES/CBC/PKCS5Padding` +`transformation`: name of the transformation, for example `DES/CBC/PKCS5Padding` -`返回值`: string +`Return value`: string ## crypto.encryptBytes(key,data,enctype,transformation) -`参数`: +`Parameters`: `key`: byte[] @@ -26,13 +26,13 @@ `enctype`: CRYPTO_AES | CRYPTO_DES -`transformation`: 转换的名称 例如 `DES/CBC/PKCS5Padding` +`transformation`: name of the transformation, for example `DES/CBC/PKCS5Padding` -`返回值`: byte[] +`Return value`: byte[] ## crypto.decrypt(key,data,enctype,transformation) -`参数`: +`Parameters`: `key`: string @@ -40,13 +40,13 @@ `enctype`: CRYPTO_AES | CRYPTO_DES -`transformation`: 转换的名称 例如 `DES/CBC/PKCS5Padding` +`transformation`: name of the transformation e.g. `DES/CBC/PKCS5Padding` -`返回值`: string +`return`: string ## crypto.decryptBytes(key,data,enctype,transformation) -`参数`: +`parameters`: `key`: byte[] @@ -54,94 +54,94 @@ `enctype`: CRYPTO_AES | CRYPTO_DES -`transformation`: 转换的名称 例如 `DES/CBC/PKCS5Padding` +`transformation`: name of the transformation e.g. `DES/CBC/PKCS5Padding` -`返回值`: byte[] +`return`: byte[] ## crypto.rc4Encrypt(key,data) -`参数`: +`parameters`: `key`: string `data`: string -`返回值`: string +`return`: string ## crypto.rc4EncryptBytes(key,data) -`参数`: +`parameters`: `key`: byte[] `data`: byte[] -`返回值`: byte[] +`return`: byte[] ## crypto.rc4Decrypt(key,data) -`参数`: +`parameters`: `key`: string `data`: string -`返回值`: string +`return`: string ## crypto.rc4DecryptBytes(key,data) -`参数`: +`parameters`: `key`: byte[] `data`: byte[] -`返回值`: byte[] +`return`: byte[] ## crypto.md5(data) -`参数`: +`parameters`: `data`: string -`返回值`: string +`return`: string ## crypto.md5Bytes(data) -`参数`: +`parameters`: `data`: byte[] -`返回值`: string +`return`: string ## crypto.sha1(data) -`参数`: +`parameters`: `data`: string -`返回值`: string +`return`: string ## crypto.sha1Bytes(data) -`参数`: +`Parameters`: `data`: byte[] -`返回值`: string +`Return value`: string ## crypto.sha256(data) -`参数`: +`Parameters`: `data`: string -`返回值`: string +`Return value`: string ## crypto.sha256Bytes(data) -`参数`: +`Parameters`: `data`: byte[] -`返回值`: string +`Return value`: string diff --git a/api/md6.md b/api/md6.md index 0e037da..a5f98b0 100644 --- a/api/md6.md +++ b/api/md6.md @@ -1,123 +1,123 @@ # device -用于获取当前设备的基础信息 +Used to obtain basic information of the current device ## device.isAdbEnabled() -判断设备 ADB 是否可用 +Determine whether the device ADB is available -`返回值`: boolean +`Return value`: boolean ## device.getSDKVersionName() -获取设备系统版本号 +Get the device system version number -`返回值`: string +`Return value`: string ## device.getSDKVersionCode() -获取设备系统版本码 +Get the device system version code -`返回值`: int +`Return value`: int ## device.getAndroidID() -获取设备 AndroidID +Get the device AndroidID -`返回值`: string +`Return value`: string ## device.getMacAddress() -获取设备 MAC 地址 +Get the device MAC address -`返回值`: string +`Return value`: string ## device.getManufacturer() -获取设备厂商 +Get the device manufacturer -`返回值`: string +`Return value`: string ## device.getModel() -获取设备型号 +Get the device model -`返回值`: string +`Return value`: string ## device.getABIs() -获取设备 ABIs +Get the device ABIs -`返回值`: string +`Return value`: string ## device.isTablet() -判断是否是平板 +Determine whether it is a tablet -`返回值`: boolean +`Return value`: boolean ## device.isDevelopmentSettingsEnabled() -开发者选项是否打开 +Whether the developer options are turned on -`返回值`: boolean +`Return value`: boolean ## device.getScreenWidth() -获取屏幕的宽度(单位:px) +Get the width of the screen (unit: px) -`返回值`: int +`Return value`: int ## device.getScreenHeight() -获取屏幕的高度(单位:px) +Get the height of the screen (unit: px) -`返回值`: int +`Return value`: int ## device.getScreenDensity() -获取屏幕密度 +Get the screen density -`返回值`: float +`Return value`: float ## device.getScreenDensityDpi() -获取屏幕密度 DPI +Get the screen density DPI -`返回值`: int +`Return value`: int ## device.isLandscape() -判断是否横屏 +Determine whether the screen is horizontal -`返回值`: boolean +`Return value`: boolean ## device.isPortrait() -判断是否竖屏 +Determine whether the screen is vertical -`返回值`: boolean +`Return value`: boolean ## device.screenShot(activity) -截屏 +Screenshot -`参数`: +`Parameters`: `activity`: Activity -`返回值`: Bitmap +`Return value`: Bitmap ## device.setClipboard(data) -设置剪贴板内容 +Set the clipboard content -`参数`: +`Parameters`: `data`: string ## device.getClipboard() -获取剪贴板内容 +Get the clipboard content -`返回值`: string +`Return value`: string diff --git a/api/md7.md b/api/md7.md index 8a5c047..1d980f1 100644 --- a/api/md7.md +++ b/api/md7.md @@ -1,50 +1,50 @@ # file -用于对文件进行相关操作 +Used to perform related operations on files ## file.isFile(path) -`参数`: +`Parameters`: `path`: string -`返回值`: boolean +`Return value`: boolean ## file.isDir(path) -`参数`: +`Parameters`: `path`: string -`返回值`: boolean +`Return value`: boolean ## file.isExists(path) -`参数`: +`Parameters`: `path`: string -`返回值`: boolean +`Return value`: boolean ## file.read(path) -`参数`: +`Parameters`: `path`: string -`返回值`: string +`Return value`: string ## file.readBytes(path) -`参数`: +`Parameters`: `path`: string -`返回值`: byte[] +`Return value`: byte[] ## file.write(path,content) -`参数`: +`Parameters`: `path`: string @@ -52,7 +52,7 @@ ## file.writeBytes(path,content) -`参数`: +`Parameters`: `path`: string @@ -60,7 +60,7 @@ ## file.append(path,content) -`参数`: +`parameters`: `path`: string @@ -68,7 +68,7 @@ ## file.appendBytes(path,content) -`参数`: +`parameters`: `path`: string @@ -76,7 +76,7 @@ ## file.copy(path,topath) -`参数`: +`parameters`: `path`: string @@ -84,7 +84,7 @@ ## file.move(path,topath) -`参数`: +`parameters`: `path`: string @@ -92,7 +92,7 @@ ## file.rename(path,newname) -`参数`: +`parameters`: `path`: string @@ -100,23 +100,23 @@ ## file.delete(path) -`参数`: +`parameters`: `path`: string ## file.getName(path) -`参数`: +`parameters`: `path`: string ## file.getSize(path) -`返回值`: long +`Return value`: long ## file.zip(path,topath,passwd) -`参数`: +`Parameters`: `path`: string @@ -126,7 +126,7 @@ ## file.zip(path,topath) -`参数`: +`Parameters`: `path`: string @@ -134,7 +134,7 @@ ## file.unzip(path,topath,passwd) -`参数`: +`Parameters`: `path`: string @@ -144,7 +144,17 @@ ## file.unzip(path,topath) -`参数`: +`Parameters`: + +`path`: string + +`topath`: string + +`passwd`: string + +## file.unzip(path,topath) + +`Parameters`: `path`: string diff --git a/api/md8.md b/api/md8.md index b48e226..d5d4e00 100644 --- a/api/md8.md +++ b/api/md8.md @@ -1,10 +1,10 @@ # http -用于进行网络请求,注意,需要被hook的应用拥有网络访问权限 +Used for network requests. Note that the hooked application needs to have network access permissions ## http.get(url,headers,function) -`参数`: +`Parameters`: `url`: string @@ -12,24 +12,24 @@ `function`: function -示例: +Example: ```javascript http.get('http://xxxxx.com', { - 'test': '1' +'test': '1' }, { - success: function (result) { - console.log(result); - }, - error: function (err) { - console.log(err); - } +success: function (result) { +console.log(result); +}, +error: function (err) { +console.log(err); +} }); ``` ## http.post(url,data,headers,function) -`参数`: +`Parameters`: `url`: string @@ -39,38 +39,38 @@ http.get('http://xxxxx.com', { `function`: function -示例: +Example: ```javascript http.post('http://xxxxx.com', { - 'user': 'me' +'user': 'me' }, { - 'test': '1' +'test': '1' }, { - success: function (result) { - console.log(result); - }, - error: function (err) { - console.log(err); - } +success: function (result) { +console.log(result); +}, +error: function (err) { +console.log(err); +} }); -//或者 +//or http.post('http://xxxxx.com', JSON.stringify({ - 'user': 'me' +'user': 'me' }), { - 'content-type': 'application/json' +'content-type': 'application/json' }, { - success: function (result) { - console.log(result); - }, - error: function (err) { - console.log(err); - } +success: function (result) { +console.log(result); +}, +error: function (err) { +console.log(err); +} }); ``` -## 注意事项 +## Notes -headers中的key和value必须都是string类型,当data为object时为表单提交,header头部会加入content-type:application/x-www-form-urlencoded,如果提交content-type:application/json,需要确定data参数类型为string +The key and value in the headers must both be string types. When data is an object, it is a form submission. The header will add content-type:application/x-www-form-urlencoded. If content-type:application/json is submitted, it is necessary to make sure that the data parameter type is string diff --git a/api/md9.md b/api/md9.md index b879bc6..a2f8457 100644 --- a/api/md9.md +++ b/api/md9.md @@ -1,43 +1,43 @@ # json -用于对字符串进行json编码解码 +Used to encode and decode strings into json ## json.toGsonString(data) -`参数`: +`Parameters`: `data`: object -`返回值`: string +`Return value`: string ## json.gsonStringToClass(data,class) -`参数`: +`Parameters`: `data`: string `class`: class -`返回值`: class +`Return value`: class ## json.toJSONString(data) -`参数`: +`Parameters`: `data`: object ## json.parseObject(data) -`参数`: +`Parameters`: `data`: string -`返回值`: JSONObject +`Return value`: JSONObject ## json.parseArray(data) -`参数`: +`Parameters`: `data`: string -`返回值`: JSONArray +`Return value`: JSONArray diff --git a/coverpage.md b/coverpage.md index b6f87dd..4cfbcb5 100644 --- a/coverpage.md +++ b/coverpage.md @@ -1,5 +1,5 @@ # JsHook Document -用js实现hook 支持java层和native层 +Use js to implement hook, support java layer and native layer -[阅读文档](#简介) +[Read the document](#Introduction) diff --git a/index.html b/index.html index fb33ba3..12cedd2 100644 --- a/index.html +++ b/index.html @@ -1,45 +1,45 @@ - JsHook Document - - - - - +JsHook Document + + + + +
@@ -50,4 +50,4 @@ - \ No newline at end of file + diff --git a/md1.md b/md1.md index 3b8acd3..7e38bb4 100644 --- a/md1.md +++ b/md1.md @@ -1,15 +1,15 @@ -# 交流 +# Communication -提供了`Telegram`沟通途径,非本页面提供的其它交流途径均非官方行为。 +Telegram is provided as a communication channel. Other communication channels not provided on this page are unofficial. -## Telegram交流群 +## Telegram communication group -交流群只提供jshook相关使用问题,脚本功能相关咨询请联系脚本作者 +The communication group only provides jshook-related usage issues. For script function related inquiries, please contact the script author -频道: +Channel: [https://t.me/jshookapp](https://t.me/jshookapp) -交流群: +Communication group: [https://t.me/jshookgroup](https://t.me/jshookgroup) diff --git a/md2.md b/md2.md index e35b8c6..2d817cf 100644 --- a/md2.md +++ b/md2.md @@ -1,117 +1,118 @@ -# 自建仓库 +# Self-built warehouse -需要搭建属于自己的脚本仓库,只需要提供以下格式的json文件地址即可,仓库界面右上角菜单中配置地址,`字段不需要的可以为null或者删除该字段` +If you need to build your own script warehouse, you only need to provide the json file address in the following format. Configure the address in the menu in the upper right corner of the warehouse interface. `Fields that are not needed can be null or deleted` -## 列表格式 +## List format -列表格式下仓库只显示脚本列表信息,不会显示仓库其他信息,如果需要更多的功能,请参考下方的完整格式 +In the list format, the warehouse only displays the script list information, and will not display other warehouse information. If you need more functions, please refer to the complete format below ```json [ - { - "author": "", - "markdown": "", - "ctime": "", - "source": "", - "id": "", - "title": "", - "type": "", - "version": "", - "url": "", - "desc": "", - "down_count": 0 - } +{ +"author": "", +"markdown": "", +"ctime": "", +"source": "", +"id": "", +"title": "", +"type": "", +"version": "", +"url": "", +"desc": "", +"down_count": 0 +} ] ``` -字段说明: +Field description: -`author`: string 显示脚本作者名称 +`author`: string Displays the name of the script author -`markdown`: string 详细说明markdown文件url地址 +`markdown`: string Detailed description of the markdown file url address -`ctime`: string 脚本创建时间,格式为:0000-00-00 +`ctime`: string Script creation time, format: 0000-00-00 -`source`: string 脚本来源url地址,比如脚本的开源github地址,非脚本的下载地址 +`source`: string Script source URL address, such as the script's open source github address, non-script download address -`id`: string 脚本唯一标识,可以用uuid +`id`: string Script unique identifier, can use uuid -`title`: string 脚本名称 +`title`: string Script name -`type`: string 两个值 rhino 或者 frida 告诉用户这是什么脚本 +`type`: string Two values ​​rhino or frida Tell the user what script this is -`version`: string 版本号 例如 1.0.0 +`version`: string Version number For example 1.0.0 -`url`: string 脚本的下载地址 +`url`: string Script download address -`desc`: string 脚本描述,控制在30字以内,简单的描述,详细描述写到markdown中 +`desc`: string Script description, controlled within 30 words, simple description, detailed description written in markdown -`down_count`: int 脚本下载数量 +`down_count`: int Script download count -## 完整格式 +## Complete format -完整格式下仓库可以用于更多的功能 +The warehouse in the complete format can be used for more functions ```json { - "name": "", - "icon": "", - "list": "", - "push": "", - "markdown": "", - "group_qq": "", - "group_tg": "", - "user_count": 0 +"name": "", +"icon": "", +"list": "", +"push": "", +"markdown": "", +"group_qq": "", +"group_tg": "", +"user_count": 0 } ``` -`name`: string 仓库名称 +`name`: string Warehouse name -`icon`: string 仓库图标的url地址 +`icon`: string URL address of warehouse icon -`list`: string 列表格式的url地址 +`list`: string URL address in list format -`push`: string 推送配置url地址 +`push`: string URL address of push configuration -`markdown`: string 仓库详细说明markdown文件url地址 +`markdown`: string URL address of markdown file with detailed warehouse information -`group_qq`: string qq群的key 在这里获取 [https://qun.qq.com/join.html](https://qun.qq.com/join.html) +`group_qq`: string QQ group key is available here [https://qun.qq.com/join.html](https://qun.qq.com/join.html) -`group_tg`: string 例如群链接为 https://t.me/jshookgroup 填写jshookgroup即可 +`group_tg`: string For example, if the group link is https://t.me/jshookgroup, fill in jshookgroup -`user_count`: int 仓库用户数量 +`user_count`: int Number of warehouse users -### 推送配置 +### Push configuration -如果仓库使用了完整格式,需要使用推送的话,push文件的json格式如下 +If the warehouse uses the full format and needs to use push, the json format of the push file is as follows ```json [ - { - "id": "", - "title": "", - "args": "", - "action": "" - } +{ +"id": "", +"title": "", +"args": "", +"action": "" +} ] ``` -jshook的设置中允许接收消息通知才能收到推送内容 +Only when jshook settings allow receiving message notifications can push content be received -为了不干扰用户,推送不会实时收到,有触发条件,当用户打开jshook或者其他注入jshook服务的应用时会开始拉取推送内容,通过id判断用户如果没有接收过开始消息通知 +In order not to interfere with users, pushes will not be received in real time. There are trigger conditions. When the user opens jshook or other applications that inject jshook services, push content will be pulled. If the user has not received the start message notification, the id will be used to determine if the user has not received it -`id`: string 推送唯一标识 +`id`: string Push unique identifier -`title`: string 消息标题 +`title`: string Message title -`args`: string 当action为markdown时填写markdown文件url地址 +`args`: string When action is markdown, fill in the markdown file URL address -`action`: string 跳转类型,固定值为markdown +`action`: string Jump type, fixed value is markdown ## DeepLink -在html中可以使用以下方式跳转jshook添加仓库订阅,其实url为仓库的订阅url地址 +In html, you can use the following method to jump to jshook to add warehouse subscriptions. In fact, the url is the subscription url address of the warehouse ```html -添加仓库订阅 +Add warehouse subscription + ``` diff --git a/md4.md b/md4.md index 10e305d..a5cb62e 100644 --- a/md4.md +++ b/md4.md @@ -1,3 +1,3 @@ -# 快速入门 +# Quick Start -准备中... +Preparing... diff --git a/md6.md b/md6.md index 2b2b507..3b8fc29 100644 --- a/md6.md +++ b/md6.md @@ -1,10 +1,10 @@ -# 安装 +# Installation -这里例举几个常见的安装激活方式 +Here are some common installation and activation methods -## 真机root环境激活 +## Activation in real root environment -你需要确保你的手机已经拥有root权限,并且已经安装以下任意一种root框架 +You need to make sure your phone has root permissions and has installed any of the following root frameworks `magisk`[https://github.com/topjohnwu/Magisk](https://github.com/topjohnwu/Magisk) @@ -12,22 +12,22 @@ `apatch`[https://github.com/bmax121/APatch](https://github.com/bmax121/APatch) -模块依赖`zygisk/riru`,你需要安装以下任意模块用于支持激活jshook +Module depends on `zygisk/riru`, You need to install any of the following modules to support the activation of jshook `zygisk`[https://github.com/Dr-TSNG/ZygiskNext](https://github.com/Dr-TSNG/ZygiskNext) `riru`[https://github.com/RikkaApps/Riru](https://github.com/RikkaApps/Riru) -**这里推荐使用zygisk,riru已经不在更新维护** +**It is recommended to use zygisk here, riru is no longer updated and maintained** -以上准备就绪后打开jshook点击`安装Magisk/kernelSU模块`按钮选择,选择对应的`zygisk/riru`版本的jshook模块进行安装,安装后重启手机即可完成激活 +After the above preparations are ready, open jshook and click the `Install Magisk/kernelSU module` button to select the corresponding `zygisk/riru` version of jshook module to install. After installation, restart the phone to complete the activation -## 虚拟机环境激活 +## Activate the virtual machine environment -使用`vmos`或者`光速虚拟机`等类似产品进行安装激活操作,操作方式同root环境激活的方式流程一样 +Use `vmos` or `Lightspeed virtual machine` and other similar products to install and activate the operation. The operation method is the same as the root environment activation method. -## 模拟器环境激活 +## Simulator environment activation -下载`MagiskDelta`,在模拟器中直接安装,再按照上面root环境激活的方式继续操作 +Download `MagiskDelta`, install it directly in the simulator, and then continue to operate according to the above root environment activation method [https://magiskdelta.com/](https://magiskdelta.com) diff --git a/md7.md b/md7.md index 69fc6c2..63e0bdd 100644 --- a/md7.md +++ b/md7.md @@ -1,29 +1,29 @@ -# 常见问题 +# Frequently Asked Questions -常见的一些问题处理方案 +Some common problem-solving solutions -## jshook相关文件在哪下载 +## Where to download jshook related files -如果你想里离线下载一些文件,可以在这里找到 +If you want to download some files offline, you can find them here -在这里下载: [https://github.com/JsHookApp/Download](https://github.com/JsHookApp/Download) +Download here: [https://github.com/JsHookApp/Download](https://github.com/JsHookApp/Download) -## 加密脚本如何支持 +## How to support encrypted scripts -目前加密脚本只能使用`fridamod`框架运行 +Currently, encrypted scripts can only be run using the `fridamod` framework -## 应用闪退 +## Application crash -部分机型实时注入脚本会直接发生闪退情况,你可以先关闭hook服务,先启动应用,等待几秒后在开启hook服务会途中开始注入,在测试之前先取消勾选脚本,排除脚本原因 +Some models will crash directly when injecting scripts in real time. You can turn off the hook service first, start the application first, wait a few seconds, and then start the injection when the hook service is turned on. Uncheck the script before testing to eliminate the script cause -## frida-server如何连接 +## How to connect to frida-server -jshook提供的frida-server默认端口号为`28042/28043` +The default port number of frida-server provided by jshook is `28042/28043` -连接示例 +Connection example ```shell -#端口转发 +#Port forwarding adb forward tcp:28042 tcp:28042 #spawn @@ -32,45 +32,45 @@ frida -H 127.0.0.1:28042 -f com.android.xxx -l test.js frida -H 127.0.0.1:28042 -n com.android.xxx -l test.js ``` -## frida-gadget如何连接 +## How to connect frida-gadget -与frida-server一样更改了端口 +The port has been changed like frida-server -连接示例 +Connection example ```shell -#端口转发 +#Port forwarding adb forward tcp:28042 tcp:28042 #attach frida -H 127.0.0.1:28042 Gadget -l test.js ``` -## 开启渲染掉激活 +## Turn on rendering and deactivate -渲染增强默认是开启的,部分机型不支持,清理应用数据后在激活状态下先关闭渲染增强在开启渲染 +Rendering enhancement is enabled by default, but not supported on some models. After cleaning the application data, turn off rendering enhancement in the activated state and then turn on rendering -## 什么是渲染增强 +## What is rendering enhancement -渲染增强指不依赖android系统的情况下直接使用底层api进行渲染,android系统无法感知存在,所以在增强模式下性能最好,且屏幕录制和截屏无法获取到渲染数据 +Rendering enhancement means using the underlying API for rendering directly without relying on the Android system. The Android system cannot sense its existence, so the performance is best in enhanced mode, and screen recording and screenshots cannot obtain rendering data -没有开启渲染增强则使用android系统的api创建渲染试图,性能会有损失,且受系统管控,屏幕录制和截屏可以获取到渲染数据 +If rendering enhancement is not enabled, the Android system API is used to create rendering views, which will result in performance loss and be controlled by the system. Screen recording and screenshots can obtain rendering data -## 如何让我的机型支持渲染增强 +## How to make my model support rendering enhancement -打开终端(例如mt管理器的终端)输入以下命令 +Open the terminal (such as the terminal of the mt manager) and enter the following command ```shell su logcat|grep ImGui ``` -命令的意思是在root用户下持续输出某个关键日志 +The command means to continuously output a key log under the root user -然后开启渲染增强把终端输出的日志发给开发者,开发者会更新模块来兼容你的机型 +Then enable rendering enhancement and send the terminal output log to the developer, who will update the module to be compatible with your model -## 在线服务出现服务器请求失败 +## Server request failure in online service -内置的在线服务可能使用了`github`链接,对于中国大陆用户访问不友好,可以自行准备`vpn`访问 +The built-in online service may use the `github` link, which is not friendly to users in mainland China. You can prepare `vpn` access by yourself -## 跨大版本更新导致jshook闪退 +## Cross-version update causes jshook to crash -例如从1.0.x更新到1.1.x这种跨大版本更新因为调整过大导致不兼容闪退,清空应用数据,删除`/data/system/jshook`和`/data/adb/jshook`,重新安装激活模块,注意,做这些操作之前请先备份脚本和订阅 +For example, a cross-version update from 1.0.x to 1.1.x may cause incompatibility crashes due to large adjustments. Clear the application data, delete `/data/system/jshook` and `/data/adb/jshook`, and reinstall the activation module. Note that you should back up the script and subscription before doing these operations. diff --git a/md8.md b/md8.md index 5cba8b2..3f059b2 100644 --- a/md8.md +++ b/md8.md @@ -1,19 +1,19 @@ -# 连接计算机 +# Connect to computer -可以使用`Visual Studio Code`实时推送脚本到手机,或者从手机获取脚本到电脑 +You can use `Visual Studio Code` to push scripts to your phone in real time, or get scripts from your phone to your computer -在这里下载vscode插件: [https://marketplace.visualstudio.com/items?itemName=JsonET.jshook-vscode-extension](https://marketplace.visualstudio.com/items?itemName=JsonET.jshook-vscode-extension) +Download the vscode plugin here: [https://marketplace.visualstudio.com/items?itemName=JsonET.jshook-vscode-extension](https://marketplace.visualstudio.com/items?itemName=JsonET.jshook-vscode-extension) -安装后在`js`文件右键或者快捷键操作 +After installation, right-click on the `js` file or use shortcut keys -`Shift+Alt+D`: 推送脚本 +`Shift+Alt+D`: Push script -`Shift+Alt+C`: 获取脚本 +`Shift+Alt+C`: Get script -`Shift+Alt+F`: 清空日志 +`Shift+Alt+F`: Clear log -`Shift+Alt+G`: 查看日志,自动刷新 +`Shift+Alt+G`: View log, automatically refresh -同步脚本时(脚本名+相对路径)与手机上一致即可,使用插件时需要jshook设置中启用服务端,使用快捷键后会出现输入ip的对话框,让电脑与手机在同一个wifi网络下。 +When synchronizing scripts (script name + relative path), just keep it the same as on the phone. When using the plugin, you need to enable the server in the jshook settings. After using the shortcut key, a dialog box for entering the ip will appear, so that the computer and the phone are on the same wifi network. -**启用服务端可以关闭jshook,不用保持在后台运行** +**Enabling the server can turn off jshook, and you don't need to keep it running in the background** diff --git a/navbar.md b/navbar.md index 6ddb610..6b86ef9 100644 --- a/navbar.md +++ b/navbar.md @@ -1,5 +1,4 @@ -* [官网首页](https://jshook.org) +* [Official website](https://jshook.org) -* 语言 - * [中文](/) - \ No newline at end of file +* Language +* [English](/) diff --git a/sidebar.md b/sidebar.md index d92a315..e3b4468 100644 --- a/sidebar.md +++ b/sidebar.md @@ -1,66 +1,65 @@ -* 前言 +* Preface - * [项目介绍](README) +* [Project Introduction](README) - * [线上交流](md1) +* [Online Communication](md1) -* 快速入门 +* Quick Start - * [安装](md6) +* [Installation](md6) - * [常见问题](md7) +* [FAQ](md7) - * [连接计算机](md8) +* [Connect Computer](md8) -* 自建仓库 +* Self-built Warehouse - * [说明](md2) +* [Instructions](md2) * Frida - * [快速入门](md4) +* [Quick Start](md4) -* API说明 +* API Instructions - * [global](api/md0) +* [global](api/md0) - * [runtime](api/md1) +* [runtime](api/md1) - * [app](api/md2) +* [app](api/md2) - * [base64](api/md3) +* [base64](api/md3) - * [media](api/md4) +* [media](api/md4) - * [crypto](api/md5) +* [crypto](api/md5) - * [device](api/md6) +* [device](api/md6) - * [file](api/md7) +* [file](api/md7) - * [http](api/md8) +* [http](api/md8) - * [curl](api/md19) +* [curl](api/md19) - * [json](api/md9) +* [json](api/md9) - * [modmenu](api/md10) +* [modmenu](api/md10) - * [moddraw](api/md17) +* [moddraw](api/md17) - * [kernel](api/md18) +* [kernel](api/md18) - * [memory](api/md20) +* [memory](api/md20) - * [storage](api/md11) +* [storage](api/md11) - * [convert](api/md12) +* [convert](api/md12) - * [dialog](api/md13) +* [dialog](api/md13) - * [view](api/md14) +* [view](api/md14) - * [keys](api/md15) +* [keys](api/md15) - * [colors](api/md16) - \ No newline at end of file +* [colors](api/md16)