How to hook fopen using Frida in Android? - hook

I have an android application into which I load a library and at some point I read a file. This is the code that is being used in the app.
FILE *fp = fopen(file_name, "r");
if (fp == NULL) {
return res;
}
Now I am attempting using Frida to hook that fopen in order to force it to return null but I do not seem to be able to find out how.
The library that is included in the application is called libnative-lib.so and my attempt in hooking fopen includes the following code for frida
Module.enumerateExports("libnative-lib.so", {
onMatch: function(e) {
if(e.type == 'function') {
if(e.name == "fopen") {
console.log("Function recognized by name");
Interceptor.attach(e.address, {
onEnter: function(args) {
console.log("Interceptor attached onEnter...");
},
onLeave: function(retval){
console.log("Interceptor attached onLeave...");
}
});
}
}
},
onComplete: function() {}
});

Instead of enumerating the exports of a specific library, you can try calling Module.findExportByName(null, "fopen") to get the address of fopen (the null argument tells frida to look through the exports of all of the loaded libraries) and use the Interceptor API the same way you did.
This should look somewhat like this:
Interceptor.attach(Module.findExportByName(null, "fopen"), {
onEnter: function(args) {
console.log("Interceptor attached onEnter...");
},
onLeave: function(args) {
console.log("Interceptor attached onLeave...");
}
}
You haven't stated exactly how your code fails, but to make sure that the library you are talking about is actually loaded in the app, you can list all of the loaded modules:
Process.enumerateModules()
.forEach(function(m) {
// You can print just the name by using m.name or the entire system path with m.path
console.log(JSON.stringify(m));
});
Another way would be using Process.enumerateModules() to find the correct module and then calling enumerateExports on the Module object you got.
This will make sure you are searching for fopen in the correct module if the name of the module is not exactly libnative-lib.so:
Process.enumerateModules()
.filter(function(m){ return m["path"].toLowerCase().indexOf("libnative") != -1 ; })
.forEach(function(mod) {
console.log(JSON.stringify(mod));
mod.enumerateExports().forEach(function (exp) {
if (exp.name.indexOf("fopen") != -1) {
console.log("fopen found!");
}
})
});
HTH, if this still doesn't solve your problem post some additional information in your question.

fopen will invoke open
I would suggest use a condition to assert it opens your specific file & not to replace/override.
Interceptor.attach(Module.findExportByName(null, "open"), {
onEnter: function(args) {
this.file_name = Memory.readCString(ptr(args[0]));
},
onLeave: function(retval) {
if ("your file name" === this.file_name) // passed from onEnter
retval.replace(0x0); // return null
}
});
BTW, if you enable the flag --enable-jit you could filter with ECMAScript6
Module.enumerateExports(moduleName).filter(ex => ex.name.includes('fopen')).forEach(ex => { .. })

Related

JSON Variable for a nodejs script

im searching for an idea to fix my problem. First of all, there is a server.exe software, that can load some stuff. But if i change something, it needs a restart, but not, if i use a json file to store account names. Look:
const allowedPlayers =
[
"Socialclubuser1",
"Socialclubuser2",
"Socialclubuser3"
]
mp.events.add("playerJoin", (player) => {
if (!allowedPlayers.includes(player.socialClub)) {
player.notify('Youre not whitelisted!');
}
});
mp.events.add("playerJoin", (player) => {
if (!allowedPlayers.includes(player.socialClub)) {
player.kick('Youre not whitelisted!');
}
});
i would use account.json, and insert there the stuff but how?
greetings
Create an account.json file and require it using require on start.
// account.json
// ["Socialclubuser1", "Socialclubuser2", "Socialclubuser3"]
const allowedPlayers = require("./account.json");
// rest of the code
mp.events.add("playerJoin", player => {
if (allowedPlayers.indexOf(player.socialClub) === -1) {
player.notify("Youre not whitelisted!");
player.kick("Youre not whitelisted!");
}
});

Electron JS write file permission problems

We are developing an Electron JS app which should get a configuration file from a server at one part. This worked until an hour ago, but now it "magically" throws a permission error. It throws a permission error when we try to write to anything. Here is what we explicitly tested:
app.getPath('userData')
"C:/test"
app.getAppPath()
We tried lauching it from an administrator elevated powershell, but still no success. This is our code snippet:
function canWrite(path, callback) {
fs.access(path, fs.W_OK, function (err) {
callback(null, !err);
});
}
function downloadFile(url, target, target_name) {
canWrite(target, function (err, isWritable) {
if (isWritable){
electronDl.download(
BrowserWindow.getFocusedWindow(),
url,
{
directory: target,
filename: target_name
}
)
console.log("Downloaded from: " + url + " to: " + target);
return true;
} else {
console.log("No permission to write to target");
return false;
}
});
}
downloadFile(REMOTEURL, app.getPath('userData'), 'sessionfile.json');
We rewrote this code, tried to change filenames, tried it without the filename (..) and are a bit out of ideas now. We furthermore implemented a file check (whether the file exists or not) and if so a deletion before executing this. We commented it out for now for debugging because it worked before.
Update:
After somebody pointed out that the outer check is pretty useless, I updated the code to this (still doesn't work):
function downloadFile(url, target) {
electronDl.download(
BrowserWindow.getFocusedWindow(),
url,
{
directory: target,
}
)
}
downloadFile(REMOTEURL, "C:/test");
Since it appears that electron-dl doesn't give clear error messages, you may want to check/create the directory beforehand as you initially did.
The basic procedure could look like this:
Check if the target directory exists.
If it exists, check if it is writable.
If it is writable, proceed to downloading.
If it is not writable, print an informative error message and stop.
If it doesn't exist, try to create it.
If this works, proceed to downloading.
If this fails, print an informative error message and stop.
The following code implements this idea (using the synchronous versions of the fs methods for simplicity). Be sure to use the asynchronous versions if required.
const electronDl = require('electron-dl')
const fs = require('fs')
function ensureDirExistsAndWritable(dir) {
if (fs.existsSync(dir)) {
try {
fs.accessSync(dir, fs.constants.W_OK)
} catch (e) {
console.error('Cannot access directory')
return false
}
}
else {
try {
fs.mkdirSync(dir)
}
catch (e) {
if (e.code == 'EACCES') {
console.log('Cannot create directory')
}
else {
console.log(e.code)
}
return false
}
}
return true
}
function downloadFile(url, target) {
if (ensureDirExistsAndWritable(target) == false) {
return
}
electronDl.download(
BrowserWindow.getFocusedWindow(),
url,
{
directory: target,
}
)
.then(
dl => console.log('Successfully downloaded to ' + dl.getSavePath())
)
.catch(
console.log('There was an error downloading the file')
)
}

validating lack of parameters in feathresjs

I've read the feathersjs documentation, but after doing a find method in a service I realized that if I don't give any query parameters, the service returns all the data, which is something I don't want. How can I define a hook to validate that there are at least one query parameter in order to proceed; otherwise, send back a 403 error (bad request).?
I have doubts in the way to do it I tried this:
app.service('myService')
.before(function(hook) {
if (hook.params.query.name === undefined){
console.log('There is no name, throw an error!');
}
})
.find({
query: {
$sort: {
year: -1
}
}
})
And I tried in hook file on hooks this (that seemed really desperate & | stupid):
function noparams (hook) {
if (hook.params.query.name === undefined){
console.log('There is no name, throw an error!');
}
}
module.exports = {
before: {
find: [ noparams(this) ] ...
}
}
but it does not compile (I don't know what to send as a parameter there), and the examples seemed to be for pre 2.0 version and on top of that the code I found seemed to be in the app.js, but all is differently coded using feathers-cli, so the examples, even in the book, aren't against the scaffolded version, which is confusing because they shows the code in a different file were should be.
Thanks.
I ended using a before hook, so the code used is this:
const errors = require('feathers-errors');
module.exports = function () {
return function (hook) {
if(hook.method === 'find'){
if (hook.params.query.name === undefined || hook.params.query.length == 0){
throw new errors.BadRequest('Invalid Parameters');
}else{
return hook;
}
}
}
};
If have used feathers-cli to generate your application (feathers v2.x) you don't need to do anything else. If is an earlier version you maybe need to add the Express error handler and it is pointed out in the documentation|Errors|REST.
Thanks.

Image.fromURL error callback

I am trying to load an image using the fromURL. The issue is that I'd like it to be able to load a default icon if it is not able to reach the Image server to download the image. Looking at the docs I did not see an error callback for the fromURL function. How are we supposed to catch that the call was not successful and therefore do the appropriate thing? It does not seem that the callback gets called at all when image load was unsuccessful.
You can use fabric.util.loadImage() method instead of fabric.Image.fromURL().
If you look at the fromURL() method implementation, internally it uses the loadImage().
The following code may help you:
fabric.util.loadImage('https://s3-eu-west-1.amazonaws.com/kienzle.dev.cors/img/image2.png', function(img) {
if(img == null) {
alert("Error!");
}else {
var image = new fabric.Image(img);
canvas.add(image).setActiveObject(image);
canvas.renderAll();
}
}, { crossOrigin: 'anonymous' });
Here is the fiddle: http://jsfiddle.net/k7moorthi/30kmn5kL/
once you have done the function, even if theres a mistake the callback keeps running, then you could check for the element (as other said) in this way:
let fabricBackgroundInstance = new fabric.Image.fromURL(imageToUse, (oImg) => {
if(oImg._element == null){
console.error('oImg', oImg._element);
return;
}
You could use getElement() to check this error.
fabric.Image.fromURL('/foo.jpg', (img) => {
if (img.getElement() === undefined) {
console.log('Failed to load image!');
return;
}
// do something on success
}
You can add the second argument isError to your callback function.
fabric.Image.fromURL("your image URL", (img, isError) => {
if (isError) {
console.log('Something Wrong with loading image');
return;
}
// do something on success
}
Also check fabric.js source code of Image.fromURL http://fabricjs.com/docs/fabric.js.html#line21471

How to tell if a script is run as content script or background script?

In a Chrome extension, a script may be included as a content script or background script.
Most stuff it does is the same, but there are some would vary according to different context.
The question is, how could a script tell which context it is being run at?
Thank you.
I think this is a fairly robust version that worked in my initial tests and does not require a slower try catch, and it identifies at least the three primary contexts of a chrome extension, and should let you know if you are on the base page as well.
av = {};
av.Env = {
isChromeExt: function(){
return !!(window['chrome'] && window['chrome']['extension'])
},
getContext: function(){
var loc = window.location.href;
if(!!(window['chrome'] && window['chrome']['extension'])){
if(/^chrome/.test(loc)){
if(window == chrome.extension.getBackgroundPage()){
return 'background';
}else{
return 'extension';
}
}else if( /^https?/.test(loc) ){
return 'content';
}
}else{
return window.location.protocol.replace(':','');
}
}
};
Well I managed to work out this:
var scriptContext = function() {
try {
if (chrome.bookmarks) {
return "background";
}
else {
return "content";
}
}
catch (e) {
return "content";
}
}
It's because an exception would be thrown if the content script tries to access the chrome.* parts except chrome.extension.
Reference: http://code.google.com/chrome/extensions/content_scripts.html
The best solution I've found to this problem comes from over here.
const isBackground = () => location.protocol === 'chrome-extension:'
The background service worker at Manifest v3 does not contain a window.
I use this as part of my extension error handling which reloads the content scripts, when i receive an Extension context invalidated error:
...
if (!self.window) {
console.warn('Background error: \n', error);
} else {
location.reload();
}
...

Resources