frida / frida-gum

Cross-platform instrumentation and introspection library written in C
https://frida.re
Other
733 stars 242 forks source link

build with quickjs: runtime-build-quick/frida.js: SyntaxError: unexpected character #724

Open milahu opened 1 year ago

milahu commented 1 year ago

build with quickjs is broken

seems like quickcompile expects a different input format

[151/214] Generating bindings/gumjs/gumjs-runtime with a custom command
FAILED: bindings/gumjs/gumcmodule-runtime.h bindings/gumjs/gumquickscript-runtime.h bindings/gumjs/gumquickscript-objc.h bindings/gumjs/gumquickscript-java.h bindings/gumjs/gumv8script-runtime.h bindings/gumjs/gumv8script-objc.h bindings/gumjs/gumv8script-java.h 
/home/milahu/nixpkgs/src/frida-gum/source/bindings/gumjs/generate-runtime.py qjs,v8 x86_64 little /home/milahu/nixpkgs/src/frida-gum/source/bindings/gumjs /home/milahu/nixpkgs/src/frida-gum/source/gum /nix/store/aw5yynzqi8cg4h733qjch53zcm4nkshr-capstone-5.0-rc2/include/capstone/capstone /nix/store/rz0irj616wmqiqwwmf0zvf86ck9qn144-frida-tinycc-unstable-2022-04-01/lib/tcc/include /home/milahu/nixpkgs/src/frida-gum/source/build/bindings/gumjs/quickcompile /home/milahu/nixpkgs/src/frida-gum/source/build/bindings/gumjs
runtime-build-quick/frida.js: SyntaxError: unexpected character
Command '[PosixPath('/home/milahu/nixpkgs/src/frida-gum/source/build/bindings/gumjs/quickcompile'), PosixPath('runtime-build-quick/frida.js'), PosixPath('runtime-build-quick/frida.qjs')]' returned non-zero exit status 1.

runtime-build-quick/frida.js: SyntaxError: unexpected character

this error is produced by

https://github.com/frida/frida-gum/blob/bd6f95d391b198d7d87264ba56f2972efc7298ec/bindings/gumjs/gumquickcompile.c#L89-L92

bindings/gumjs/runtime-build-quick/frida.js looks like

πŸ“¦222 /runtime/entrypoint-quickjs.js.map
53 /runtime/entrypoint-quickjs.js
1369 /runtime/console.js.map
1387 /runtime/console.js
16641 /runtime/core.js.map
11873 /runtime/core.js
1511 /runtime/error-handler-quickjs.js.map
763 /runtime/error-handler-quickjs.js
2643 /runtime/hexdump.js.map
1238 /runtime/hexdump.js
2496 /runtime/message-dispatcher.js.map
1225 /runtime/message-dispatcher.js
βœ„
{"version":3,"file":"entrypoint-quickjs.js","names":["require"],"sourceRoot":"/home/milahu/nixpkgs/src/frida-gum/source/build/bindings/gumjs/runtime/","sources":["entrypoint-quickjs.js"],"mappings":"AAAAA,QAAQ,UACRA,QAAQ"}
βœ„
require("./core"),require("./error-handler-quickjs");
βœ„
{"version":3,"file":"console.js","names":["hexdump","require","sendLogMessage","level","values","message","type","payload","map","parseLogArgument","join","_send","JSON","stringify","value","ArrayBuffer","undefined","module","exports","constructor","_Console_counters","set","this","__classPrivateFieldSet","Map","info","args","log","debug","warn","error","count","label","newValue","__classPrivateFieldGet","get","countReset","has","delete"],"sourceRoot":"/home/milahu/nixpkgs/src/frida-gum/source/build/bindings/gumjs/runtime/","sources":["console.js"],"mappings":"guBAAA,MAAMA,EAAUC,QAAQ,aA8CxB,SAASC,EAAeC,EAAOC,GAC7B,MACMC,EAAU,CACdC,KAAM,MACNH,MAAOA,EACPI,QAJWH,EAAOI,IAAIC,GAAkBC,KAAK,MAM/CC,MAAMC,KAAKC,UAAUR,GAAU,KACjC,CAEA,SAASI,EAAiBK,GACxB,OAAIA,aAAiBC,YACZf,EAAQc,QAEHE,IAAVF,EACK,YAEK,OAAVA,EACK,OAEFA,CACT,C,cAvBAG,OAAOC,QA1CP,MAGEC,cAFAC,EAAAC,IAAAC,UAAA,GAGEC,EAAAD,KAAIF,EAAa,IAAII,IAAK,IAC5B,CAEAC,QAAQC,GACNxB,EAAe,OAAQwB,EACzB,CAEAC,OAAOD,GACLxB,EAAe,OAAQwB,EACzB,CAEAE,SAASF,GACPxB,EAAe,QAASwB,EAC1B,CAEAG,QAAQH,GACNxB,EAAe,UAAWwB,EAC5B,CAEAI,SAASJ,GACPxB,EAAe,QAASwB,EAC1B,CAEAK,MAAMC,EAAQ,WACZ,MAAMC,GAAYC,EAAAZ,KAAIF,EAAA,KAAWe,IAAIH,IAAU,GAAK,EACpDE,EAAAZ,KAAIF,EAAA,KAAWC,IAAIW,EAAOC,GAC1BX,KAAKK,IAAI,GAAGK,MAAUC,IACxB,CAEAG,WAAWJ,EAAQ,WACbE,EAAAZ,KAAIF,EAAA,KAAWiB,IAAIL,GACrBE,EAAAZ,KAAIF,EAAA,KAAWkB,OAAON,GAEtBV,KAAKO,KAAK,cAAcG,oBAE5B"}
βœ„
var e,t=this&&this.__classPrivateFieldSet||function(e,t,r,o,n){if("m"===o)throw new TypeError("Private method is not writable");if("a"===o&&!n)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!n:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===o?n.call(e,r):n?n.value=r:t.set(e,r),r},r=this&&this.__classPrivateFieldGet||function(e,t,r,o){if("a"===r&&!o)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!o:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===r?o:"a"===r?o.call(e):o?o.value:t.get(e)};const o=require("./hexdump");function n(e,t){const r={type:"log",level:e,payload:t.map(i).join(" ")};_send(JSON.stringify(r),null)}function i(e){return e instanceof ArrayBuffer?o(e):void 0===e?"undefined":null===e?"null":e}e=new WeakMap,module.exports=class{constructor(){e.set(this,void 0),t(this,e,new Map,"f")}info(...e){n("info",e)}log(...e){n("info",e)}debug(...e){n("debug",e)}warn(...e){n("warning",e)}error(...e){n("error",e)}count(t="default"){const o=(r(this,e,"f").get(t)??0)+1;r(this,e,"f").set(t,o),this.log(`${t}: ${o}`)}countReset(t="default"){r(this,e,"f").has(t)?r(this,e,"f").delete(t):this.warn(`Count for '${t}' does not exist`)}};
βœ„
{"version":3,"file":"core.js","names":["Console","require","hexdump","MessageDispatcher","engine","global","messageDispatcher","makeStubBridge","Object","freeze","available","defineProperties","rpc","enumerable","value","exports","recv","type","callback","arguments","length","registerCallback","send","payload","data","message","_send","JSON","stringify","setTimeout","func","delay","args","_setTimeout","apply","setInterval","_setInterval","setImmediate","clearImmediate","id","clearTimeout","int64","Int64","uint64","UInt64","ptr","str","NativePointer","NULL","console","ObjC","configurable","get","m","Frida","_loadObjC","_objc","defineProperty","Swift","_loadSwift","_swift","Java","_loadJava","_java","pointerPrototype","prototype","numberWrapperEquals","rhs","this","compare","getOwnPropertyNames","Memory","forEach","methodName","write","read","indexOf","call","klass","equals","Script","load","async","name","source","_load","import","_nextTick","nextTick","bind","makeEnumerateApi","Kernel","makeEnumerateRanges","scan","address","size","pattern","callbacks","onSuccess","onFailure","request","Promise","resolve","reject" ..........

frida.js is producd by frida-compile

https://github.com/frida/frida-compile/blob/1db333b394fed68ba2aeff4a8a96298ba593c676/src/compiler.ts#L609

            chunks.push("πŸ“¦\n")

the "package marker" also appears in

frida-gum/bindings/gumjs/gumquickscriptbackend.c:  const gchar * package_marker = "πŸ“¦\n";
frida-gum/bindings/gumjs/gumv8script.cpp:  const gchar * package_marker = "πŸ“¦\n";

versions

works in frida CI

meson setup --default-library static -Dgumjs=enabled frida-gum
...
Dependency quickjs found: YES 2021-03-27-frida (cached)
...
[151/214] Generating bindings/gumjs/gumjs-runtime with a custom command

related #723

related #713 - unicode package symbol

milahu commented 1 year ago

bindings/gumjs/runtime-build-quick/frida.js looks like

πŸ“¦222 /runtime/entrypoint-quickjs.js.map

this is wrong, should be valid javascript

(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var 
a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
const n = require("./hexdump");

class e {
  #n;
  constructor() {
    this.#n = new Map;
  }
// ...

problem: i was using a wrong version of frida-compile

actual vs expected:

-  "version": "16.1.8",
+  "version": "10.2.5",

version of frida-compile is declared in generate-runtime.py

https://github.com/frida/frida-gum/blob/bd6f95d391b198d7d87264ba56f2972efc7298ec/bindings/gumjs/generate-runtime.py#L14-L22