As the title stated, how can I hook os_log by using Frida?
Tried below, not working.
Interceptor.attach(Module.findExportByName("libSystem.B.dylib", "os_log"), {
onEnter: function (args) {
console.log(args[0] + args[1]);
}
});
Enabling all logs
var m = 'libsystem_trace.dylib';
// bool os_log_type_enabled(os_log_t oslog, os_log_type_t type);
var isEnabledFunc = Module.findExportByName(m, 'os_log_type_enabled');
// _os_log_impl(void *dso, os_log_t log, os_log_type_t type, const char *format, uint8_t *buf, unsigned int size);
var logFunc = Module.findExportByName(m, '_os_log_impl');
Interceptor.attach(isEnabledFunc, {
onLeave: function (ret) {
// console.log('log_enabled', ret);
ret.replace(0x1);
}
});
Interceptor.attach(logFunc, {
onEnter: function (a) {
var type = a[2]; // https://github.com/darlinghq/darling/blob/master/src/libc/os/log.h#L105
var format = a[3];
if (type != 0x2) {
console.log(JSON.stringify({
type: type,
format: format.readCString(),
//buf: a[4].readPointer().readCString()
}, null, 2));
}
}
})
Related
I'm using frida on an APK and I'm trying to print out which function is being called, and especially which parameters are sent to it. My environment is set correctly as I can print out classes, and perform various actions in accordance to the docs.
This is the closest i've found:
https://codeshare.frida.re/#razaina/get-a-stack-trace-in-your-hook/
But the code gives out errors (ThreadDef undefined and so on)
And the frida docs didn't help me get where I'm trying to.
Any guidance? suggestions? help?
The code from codeshare#razaina has bugs which can be easily fixed (threadef != ThreadDef)
var printBacktrace = function () {
Java.perform(function() {
var JLog = Java.use('android.util.Log'), JException = Java.use('java.lang.Exception');
// getting stacktrace by throwing an exception
console.warn(JLog.getStackTraceString(JException.$new()));
});
};
Just call printBacktrace() w/e you want to see who called your hooked function.
If you want to hook all the methods of Java class you can use this snippet;
var Color = {
RESET: "\x1b[39;49;00m", Black: "0;01", Blue: "4;01", Cyan: "6;01", Gray: "7;11", Green: "2;01", Purple: "5;01", Red: "1;01", Yellow: "3;01",
Light: {
Black: "0;11", Blue: "4;11", Cyan: "6;11", Gray: "7;01", Green: "2;11", Purple: "5;11", Red: "1;11", Yellow: "3;11"
}
};
/**
*
* #param input.
* If an object is passed it will print as json
* #param kwargs options map {
* -l level: string; log/warn/error
* -i indent: boolean; print JSON prettify
* -c color: #see ColorMap
* }
*/
var LOG = function (input, kwargs) {
kwargs = kwargs || {};
var logLevel = kwargs['l'] || 'log', colorPrefix = '\x1b[3', colorSuffix = 'm';
if (typeof input === 'object')
input = JSON.stringify(input, null, kwargs['i'] ? 2 : null);
if (kwargs['c'])
input = colorPrefix + kwargs['c'] + colorSuffix + input + Color.RESET;
console[logLevel](input);
};
var printBacktrace = function () {
Java.perform(function() {
var android_util_Log = Java.use('android.util.Log'), java_lang_Exception = Java.use('java.lang.Exception');
// getting stacktrace by throwing an exception
LOG(android_util_Log.getStackTraceString(java_lang_Exception.$new()), { c: Color.Gray });
});
};
function traceClass(targetClass) {
var hook;
try {
hook = Java.use(targetClass);
} catch (e) {
console.error("trace class failed", e);
return;
}
var methods = hook.class.getDeclaredMethods();
hook.$dispose();
var parsedMethods = [];
methods.forEach(function (method) {
var methodStr = method.toString();
var methodReplace = methodStr.replace(targetClass + ".", "TOKEN").match(/\sTOKEN(.*)\(/)[1];
parsedMethods.push(methodReplace);
});
uniqBy(parsedMethods, JSON.stringify).forEach(function (targetMethod) {
traceMethod(targetClass + '.' + targetMethod);
});
}
function traceMethod(targetClassMethod) {
var delim = targetClassMethod.lastIndexOf('.');
if (delim === -1)
return;
var targetClass = targetClassMethod.slice(0, delim);
var targetMethod = targetClassMethod.slice(delim + 1, targetClassMethod.length);
var hook = Java.use(targetClass);
var overloadCount = hook[targetMethod].overloads.length;
LOG({ tracing: targetClassMethod, overloaded: overloadCount }, { c: Color.Green });
for (var i = 0; i < overloadCount; i++) {
hook[targetMethod].overloads[i].implementation = function () {
var log = { '#': targetClassMethod, args: [] };
for (var j = 0; j < arguments.length; j++) {
var arg = arguments[j];
// quick&dirty fix for java.io.StringWriter char[].toString() impl because frida prints [object Object]
if (j === 0 && arguments[j]) {
if (arguments[j].toString() === '[object Object]') {
var s = [];
for (var k = 0, l = arguments[j].length; k < l; k++) {
s.push(arguments[j][k]);
}
arg = s.join('');
}
}
log.args.push({ i: j, o: arg, s: arg ? arg.toString(): 'null'});
}
var retval;
try {
retval = this[targetMethod].apply(this, arguments); // might crash (Frida bug?)
log.returns = { val: retval, str: retval ? retval.toString() : null };
} catch (e) {
console.error(e);
}
LOG(log, { c: Color.Blue });
return retval;
}
}
}
// remove duplicates from array
function uniqBy(array, key) {
var seen = {};
return array.filter(function (item) {
var k = key(item);
return seen.hasOwnProperty(k) ? false : (seen[k] = true);
});
}
var Main = function() {
Java.perform(function () { // avoid java.lang.ClassNotFoundException
[
// "java.io.File",
'java.net.Socket',
'com.package.MyCustomClass'
].forEach(traceClass);
});
};
Java.perform(Main);
I am using cordova-plugin-ble-contral,I write on ios but it return 'null',on android return 'ok'.I can not write well on ios.
I can write well on android and ios, I make hybird APP.
connectTo() {
var that = this;
var Hex = "";
Hex += addZero(stringToSixteen(this.ssid), 32);
Hex += "07";
Hex += addZero(stringToSixteen(this.password), 64);
Hex += "A5A5";
var data = HexString2Bytes(Hex);
let length = Math.ceil(data.byteLength / 20);
var success = function(reason) {
// it will return null?
that.$router.push({
name: "isConnect",
query: {
deviceId: that.deviceId,
ssid: that.ssid,
password: that.password
}
});
};
var failure = function(reason) {
alert(reason);
that.$router.push({
name: "isConnect",
query: {
deviceId: that.deviceId,
ssid: that.ssid,
password: that.password
}
});
};
//分包发送msg
for (let i = 0; i < length; i++) {
var buffers = data.slice(i * 20, (i + 1) * 20);
ble.writeWithoutResponse(
this.deviceId,
this.serviceUUID,
this.characteristicToWrite,
buffers,
success,
failure
);
}
},
It show I write well but it does not send message in fact.
I want to make a basic example Firefox add-on using js-ctype. First, I made a .dll file with a simple C code:
#include "stdio.h"
extern "C"
{
__declspec(dllexport) int add(int a, int b) { return a + b; }
}
The library file is fine. I tested it in another project.
I load it by js-ctypes code:
var {Cu , Cc, Ci} = require("chrome");
Cu.import("resource://gre/modules/ctypes.jsm", null);
Cu.import("resource://gre/modules/Services.jsm");
var self = require("sdk/self");
var prompts = Cc["#mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService);
var dataUrl = self.data.url("Js-CtypeLib.dll");
dataUrl = Services.io.newURI(dataUrl,null,null).QueryInterface(Ci.nsIFileURL).file.path;
var lib, add;
try{
console.log("Load library");
lib = ctypes.open("Js-CtypeLib.dll");
try{
declareFunc();
}
catch(e){
console.log("Error declare function");
}
}
catch(e){
console.log("Error load Library!");
}
function declareFunc(){
add = lib.declare("add", ctypes.default_abi, ctypes.int, ctypes.int, ctypes.int);
}
function test(){
var rs = add(4,2);
prompts.alert(null, "Result: ", rs);
lib.close();
}
exports.test = test;
and then, I call support.js file by index.js
var buttons = require('sdk/ui/button/action');
var tabs = require("sdk/tabs");
var support = require("./support.js");
var button = buttons.ActionButton({
id: "mozilla-link",
label: "Visit Mozilla",
icon: {
"16": "./images/icon-16.png",
"32": "./images/icon-32.png",
"64": "./images/icon-64.png"
},
onClick: handleClick}
);
function handleClick(state) {
support.test();
}
Finally, in cmd, I run it and get:
Component returned failure code: 0x80004002 (NS_NOINTERFACE) [nsIFileURL.file]
Full error text:
You need to mark your addon as "unpacked" in the package.json. Then you must use a file:// uri in the call to ctypes.open(file_uri_here).
To get a file uri of a file in your addon you would do this:
Components.utils.import("resource://gre/modules/Services.jsm");
var cr = Components.classes['#mozilla.org/chrome/chrome-registry;1'].getService(Components.interfaces.nsIChromeRegistry);
var chromeURI_myLib = Services.io.newURI('chrome://youraddon/content/mySubFolder/myCFunctionsForUnix.so', 'UTF-8', null);
var localFile_myLib = cr.convertChromeURL(chromeURI_myLib);
var jarPath_myLib = localFile_myLib.spec; // "jar:file:///C:/Users/Vayeate/AppData/Roaming/Mozilla/Firefox/Profiles/aecgxse.Unnamed%20Profile%201/extensions/youraddon#jetpack.xpi!/mySubFolder/myCFunctionsForUnix.so"
var filePath_myLib = localFilemyLib.path;
ctypes.open(filePath_myLib);
I am developing (trying) a firefox extension to intercept HTTP 500 responses status code and cancel the original request and sending it with another custom protocol.
I am trying to implement and observer and a listener but it is not working for me. I am new in this and I am sure that I am doing something wrong. Can anyone help me to figure out how to do this.
I followed the http://www.softwareishard.com/blog/firebug/nsitraceablechannel-intercept-http-traffic/ tutorial and It is not working, maybe I am not binding or using the component in the correct manner.
My code is:
Chrome.manifest
content lightweightandsecureprotocol chrome/content/
content lightweightandsecureprotocol chrome/content/ contentaccessible=yes
locale lightweightandsecureprotocol en-US crhome/locale/en-US/
skin lightweightandsecureprotocol classic/1.0 chrome/skin/
style chrome://global/content/customizeToolbar.xul chrome://lightweightandsecureprotocol/skin/browser.css
overlay chrome://browser/content/browser.xul chrome://lightweightandsecureprotocol/content/browser.xul
component {90b7bac4-78fc-4193-a2d9-1ed7a4f675eb} components/HttpResponseObserver.js
Source Code :
/chrome/content/Browser.xul
<?xml version="1.0"?>
<?xml-stylesheet type="text/css"
href="chrome://lightweightandsecureprotocol/skin/browser.css"?>
<overlay id="overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/x-javascript" src="chrome://lightweightandsecureprotocol/components/HttpResponseObserver.js"/>
<script>
try{
var myComponent = Components.classes['#patricia.figueroa.millan/httpresponseobserver;1']
.getService().wrappedJSObject;
}catch(anError){
dump("ERROR:" + anError);
}
</script>
</overlay>
Source Code:
/components/HttpResponseObserver.js
const nsISupports = Components.interfaces.nsISupports;
const CLASS_ID = Components.ID("90b7bac4-78fc-4193-a2d9-1ed7a4f675eb");
const CLASS_NAME = "Http Response Observer";
const CONTRACT_ID = "#patricia.figueroa.millan/httpresponseobserver;1";
function HttpResponseObserver() {
this.wrappedJSObject = this;
}
HttpResponseObserver.prototype = {
observe: function(aSubject, aTopic, aData){
if(aTopic=="http-on-examine-response"){
let httpChannel=aSubject.QueryInterface(Components.interfaces.nsIHttpChannel);
if(httpChannel.responseStatus== 555){
alert("555 Status code in Response ");
}
var newListener=new TracingListener();
aSubject.QueryInterface(Components.interfaces.nsITraceableChannel);
newListener.originalListener=aSubject.setNewListner(newListener);
}
}
QueryInterface: function(aIID)
{
if (!aIID.equals(nsISupports))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
}
}
var HttpResponseObserverFactory = {
singleton: null,
createInstance: function (aOuter, aIID)
{
if (aOuter != null)
throw Components.results.NS_ERROR_NO_AGGREGATION;
if (this.singleton == null)
this.singleton = new HttpResponseObserver();
return this.singleton.QueryInterface(aIID);
}
};
var HttpResponseObserverModule = {
registerSelf: function(aCompMgr, aFileSpec, aLocation, aType)
{
aCompMgr = aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
aCompMgr.registerFactoryLocation(CLASS_ID, CLASS_NAME, CONTRACT_ID, aFileSpec, aLocation, aType);
},
unregisterSelf: function(aCompMgr, aLocation, aType)
{
aCompMgr = aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
aCompMgr.unregisterFactoryLocation(CLASS_ID, aLocation);
},
getClassObject: function(aCompMgr, aCID, aIID)
{
if (!aIID.equals(Components.interfaces.nsIFactory))
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
if (aCID.equals(CLASS_ID))
return HttpResponseObserverFactory;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
canUnload: function(aCompMgr) { return true; }
};
function NSGetModule(aCompMgr, aFileSpec) { return HttpResponseObserverModule; }
//LISTENER
function TracingListener() {
this.originalListener = null;
}
TracingListener.prototype =
{
onDataAvailable: function(request, context, inputStream, offset, count) {
this.originalListener.onDataAvailable(request, context, inputStream, offset, count);
},
onStartRequest: function(request, context) {
this.originalListener.onStartRequest(request, context);
},
onStopRequest: function(request, context, statusCode) {
this.originalListener.onStopRequest(request, context, statusCode);
},
QueryInterface: function (aIID) {
if (aIID.equals(Components.interfaces.nsIStreamListener) ||
aIID.equals(Components.interfaces.nsISupports)) {
return this;
}
throw Components.results.NS_NOINTERFACE;
}
}
Thanks in advance. :D
that example is very complex, the main purpose of that traceable channel example is to get a COPY of the sourcecode that gets loaded at that uri.
const { interfaces: Ci, utils: Cu, classes: Cc, results: Cr } = Components;
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/devtools/Console.jsm');
var observers = {
'http-on-examine-response': {
observe: function (aSubject, aTopic, aData) {
console.info('http-on-examine-responset: aSubject = ' + aSubject + ' | aTopic = ' + aTopic + ' | aData = ' + aData);
var httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
if (httpChannel.responseStatus == 555) {
console.log('555 Status code in Response for request url = ' + httpChannel.URI.spec);
//httpChannel.cancel(Cr.NS_BINDING_ABORTED); //you might not need this, i think the redirectTo function handles aborting
httpChannel.redirectTo(Services.io.newURI('about:got bad response status so redirected you', null, null));
}
},
reg: function () {
Services.obs.addObserver(observers['http-on-examine-response'], 'http-on-modify-request', false);
},
unreg: function () {
Services.obs.removeObserver(observers['http-on-examine-response'], 'http-on-modify-request');
}
}
};
to register the observer on startup of addon run this:
//register all observers
for (var o in observers) {
observers[o].reg();
}
and on shutdown of addon unregister all observers like this:
//unregister all observers
for (var o in observers) {
observers[o].unreg();
}
Hi I have a small flash as below
public function startApp () : Void
{
mcWindowRoot.refToClass = this;
mcNext = mcWindowRoot;
_oLogoutDelegate = Delegate.create (this, onLogoutHandler);
_oWindowManagerRef.addEventListener ("onLogout", _oLogoutDelegate);
loadWhatNext ();
}
/**
* Enter description here
*
*/
function loadWhatNext (mc : MovieClip) : Void
{
var doneFinish = mcNext.container.attachMovie ("done", "done", mcNext.container.getNextHighestDepth ());
//var returnPage = mcNext.container.attachMovie ("item", "item", mcNext.container.getNextHighestDepth () ,
//{
//_x : 135, _y : 230
//});
var miRefTemp = _oWindowManagerRef;
//returnPage.item_txt.htmlText = _level0.account_Return;
//returnPage.onPress =
doneFinish.onPress = function ()
{
trace ("AccountNext returnPage.onPress doneFinish.onPress" )
trace ("AccountNext miRefTemp " + miRefTemp)
trace ("AccountNext this.refToClass " + this._parent._parent.refToClass)
trace ("AccountNext this " + this)
this._parent._parent.refToClass.closeWindow ();
_oShell.loadWindow( "", null);
}
if (aNextdata != undefined && aNextdata.length > 0)
{
for (var i = 0 ; i < 3; i ++)
{
if (aNextdata [i].text != undefined)
{
var tempItem = mcNext.copy.attachMovie ("item", "item" + i, i,
{
_x : 143, _y : 150 + (i * 20)
});
tempItem.item_txt.htmlText = aNextdata [i].text;
tempItem.url = aNextdata [i].link;
tempItem.refToClass = _refWindow;
var asInterpreter = new asFunctionInterpreter (_oWindowManagerRef._oWindowManagerRef.oController.propertiesMap.get ("BaseURL") , this);
var deepLinks : Object = new Object ();
deepLinks = asInterpreter.getAsSingleURL ( aNextdata [i].link );
tempItem.deepLinks = deepLinks;
trace("Next :: LINKS : " + tempItem.wModule );
tempItem.oShell = _oShell;
tempItem.onPress = function ()
{
if (this.deepLinks.type == "internal")
{
this.oShell.loadWindow( this.deepLinks.wModule , this.deepLinks.wParams);
}
else
{
getURL (this.deepLinks.link, "_blank");
}
this.refToClass.closeWindow ();
}
}
}
} else
{
trace ("end tab " + _refWindow);
}
}
/**
* Enter description here
*
* #param evt
*/
private function onLogoutHandler (evt : Object) : Void
{
_oWindowManagerRef.removeEventListener ("onLogout", _oLogoutDelegate);
closeWindow ();
}
/**
* Enter description here
*
*/
public function closeMyWindow () : Void
{
_global._doNav ('windowType:wclose')
}
/**
* Enter description here
*
*/
public function removeMyWindow () : Void
{
_oWindowManagerRef.removeWindow (idWindow);
}
}
If you can see from this part of the code
if (aNextdata != undefined && aNextdata.length > 0)
I am getting three links one below the other but my problem is only the first link is opening in a new page which is supposed to open in the same page so what should I do for this Please help me thankyou.
Hard to say from your question, but it could be the getUrl-call that is causing your link to open in a new window. The second, optional, parameter to getUrl specifies the window in which the link should open. If you replace
getURL (this.deepLinks.link, "_blank");
with
getURL (this.deepLinks.link);
Your link should open in the same window.