I'm tring to get $handle use frida,but it return undefined - frida

this is my code:
Java.perform(function(){
var dexclassLoader = Java.use("dalvik.system.DexClassLoader");
var ClassUse = Java.use("java.lang.Class");
dexclassLoader.loadClass.overload('java.lang.String').implementation = function(name){
var result = this.loadClass(name,false);
console.log(result);
console.log(result.$handle);
send(result);
return result;
}
});
this is result:
class android.widget.LinearLayout
undefined
[*] <instance: java.lang.Class>
I can't get JSON object of the class like this:
class cn.chaitin.geektan.crackme.MainActivityPatch
[*] {'$handle': '0x1d2006ee', '$weakRef': 693}

Related

Frida (android) - why java.lang.StringBuilder append is not hooked

I'm studying frida.
As an example, I simply created a string through the StringBuilder and append it.
I hooked "append" using "frida".
But it doesn't work.
String val;
val = "Log Data....";
StringBuilder log = new StringBuilder("LOG : ").append(val);
log.append("[[");
log.append("]]");
Java.perform(function () {
var StringBuilder = Java.use('java.lang.StringBuilder');
var ctor = StringBuilder.$init.overload('java.lang.String');
ctor.implementation = function (arg) {
var log_arg = '';
var result = ctor.call(this, arg);
if (arg !== null) {
log_arg = arg.toString();
}
console.log('new StringBuilder("' + log_arg + '");');
return result;
};
var append = StringBuilder.append.overload('java.lang.String');
append.implementation = function (arg) {
var result = append.call(this, arg);
var log_arg = '';
if (result !== null) {
log_arg = result.toString();
}
console.log('StringBuilder.append1(); => ' + log_arg);
return result;
};
});
Result :
new StringBuilder("LOG : ");
" Log Data....[[]] " - I can't see the message.... Probably not hooking.
Your hook to append isn't hooking the instance that was initialized.
var ctor = StringBuilder.$init.overload('java.lang.String');
This is where you initialize and allocate, so you need to make the call here.
Something more like
var append = ctor.implementation = function(arg)...
should work. But because StringBuilder has a ton of overloads to cover a ton of data types and it can get called a ton of times, it's much easier to simply hook its toString method so that you don't have to do any casting or write a ton of overloads.
const StringBuilder = Java.use('java.lang.StringBuilder');
StringBuilder.toString.implementation = function () {
var res = this.toString();
var tmp = "";
if (res !== null){
tmp = res.toString().replace("/n", "");
console.log(tmp);
}
return res;
};
should hook the actual string that it will output.

OpenUI5: Where is the data gone, loaded by sap.ui.model.odata.v2.ODataModel()?

I have been googling and testing around for quite a few days with no success. If someone could give me a hint to point me into the right direction, then I would greatly appreciate that.
What is my target: to get some data from an OData service and show it in an UI5 oTable. Later on, I will have to do the CRUD-operations, but for now the aim is just to show the data successfully.
What I have got so far: I have an MVC project. I have created an OpenUI5Controller.cs, whose purpose is to represent an ODataService:
public class OpenUI5Controller : Controller
{
private MyEntities myEntities = new MyEntities();
public JsonResult GetAllContragents()
{
try
{
IQueryable<Contragent> contragents = myEntities.Contragent.OrderBy(x => x.Code);
// for now, take the first 100 only
contragents = contragents.Take(100);
var jsonData = new
{
rows = contragents.ToList()
//rows = "123"
};
var res = Json(jsonData, JsonRequestBehavior.AllowGet);
return res;
}
catch (Exception e)
{
LoggingService.WriteLog("Error in OpenUI5Controller.GetAllContragents()", e);
return null;
}
}
}
After that, I try to consume the data like this:
var oModel = new sap.ui.model.odata.v2.ODataModel('/OpenUI5/GetAllContragents', {
//maxDataServiceVersion: '2.0',
json: true,
skipMetadataAnnotationParsing: true,
// none of those callbacks is ever triggered, even the requestFailed...!?
requestSent: function (a, b, c) {
debugger;
var trgrwg = oModel.getData();
var vfewgvfewgv = oModel.getProperty('/');
var vfewgvfewgv2 = oModel.getProperty('/rows');
var vfewgvfewgv3 = oModel.getProperty('rows');
},
requestFailed: function (a, b, c) {
debugger;
var trgrwg = oModel.getData();
var vfewgvfewgv = oModel.getProperty('/');
var vfewgvfewgv2 = oModel.getProperty('/rows');
var vfewgvfewgv3 = oModel.getProperty('rows');
},
requestCompleted: function (a, b, c) {
debugger;
var trgrwg = oModel.getData();
var vfewgvfewgv = oModel.getProperty('/');
var vfewgvfewgv2 = oModel.getProperty('/rows');
var vfewgvfewgv3 = oModel.getProperty('rows');
},
batchRequestCompleted: function (a, b, c) {
debugger;
var trgrwg = oModel.getData();
var vfewgvfewgv = oModel.getProperty('/');
var vfewgvfewgv2 = oModel.getProperty('/rows');
var vfewgvfewgv3 = oModel.getProperty('rows');
},
useBatch : false
});
var trgrwg = oModel.getData();
var vfewgvfewgv = oModel.getProperty('/');
var vfewgvfewgv2 = oModel.getProperty('/rows');
var vfewgvfewgv3 = oModel.getProperty('rows');
var vfewgvfewgv4 = oModel.getProperty('contragents');
var vfewgvfewgv5 = oModel.getProperty('/contragents');
var vfewgvfewgv6 = oModel.getProperty('Contragents');
var vfewgvfewgv7 = oModel.getProperty('/Contragents');
debugger;
When stopping at this breakpoint, I see this in the Chrome Developer Tools:
Moving further, I came accross this and tried to read() those contragents:
oModel.read('/Contragents', {
success: function (event) {
debugger;
// event.root I guess should be the received data as jsonString
// As I guess, I will have to get it and give it to oModel.oData manually, or am I wrong? I guess this would cause update(), delete()... calls to fail later on. Anyways...
sap.ui.getCore().setModel(oModel); // https://archive.sap.com/discussions/thread/3746588 - seems not to work like this
if (withJsonModel !== true) { https://help.sap.com/saphelp_uiaddon20/helpdata/en/12/32241b99d7437ba3614698d53dfa4b/content.htm
oTable.setModel(oModel);
oTable.bindRows("/");
//oTable.bindRows("/rows");
oTable.placeAt('tblContragents', "only");
}
},
error: function (event) {
debugger;
}
});
Here, neither success, nor error callback gets ever triggered.
After this read() attempt, I have again:
var trgrwg = oModel.getData();
var vfewgvfewgv = oModel.getProperty('/');
var vfewgvfewgv2 = oModel.getProperty('/rows');
var vfewgvfewgv3 = oModel.getProperty('rows');
var vfewgvfewgv4 = oModel.getProperty('contragents');
var vfewgvfewgv5 = oModel.getProperty('/contragents');
var vfewgvfewgv6 = oModel.getProperty('Contragents');
var vfewgvfewgv7 = oModel.getProperty('/Contragents');
and I see this:
After that, I have oTable = new sap.ui.table.Table(...);
Finally, I try this:
sap.ui.getCore().setModel(oModel);
//oTable.setModel(oModel); // or maybe should be this one directly?
oTable.bindRows("/Contragents");
oTable.placeAt('tblContragents', "only");
As a result, I get an empty table.
I suppose I should tell you what I see in Fiddler as well: I see this request: 1 200 HTTP localhost:55714 /OpenUI5/GetAllContragents/$metadata
As a result in the TextView of the response section, I see the data as json, that I need to show in the table.
How to make it work and show the data in the table?
edit from 02.02.2017: I have 1% of progress. After some more and more testing and googling, I decided to try it like this.
First of all, some time ago (can't really remember when), after seeing a good example for OdataServices, I decided to create a dedicated controller like this:
public class ContragentsController : ODataController
{
private MyEntities db = new MyEntities();
//public System.Web.Mvc.JsonResult GetContragents()
public string GetContragents()
{
try
{
IQueryable<Contragent> contragents = db.Contragent.OrderBy(x => x.Code);
// for now, give me first 100
contragents = contragents.Take(100);
var jsSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var rows = jsSerializer.Serialize(contragents.ToList());
//var jsonData = new
//{
// rows = model
//};
//var res = new System.Web.Mvc.JsonResult();
//res.Data = jsonData;
//res.JsonRequestBehavior = System.Web.Mvc.JsonRequestBehavior.AllowGet;
return rows;
}
catch (Exception e)
{
//...some errorLogging
return null;
}
}
After that, I changed the call to ODataModel() like this:
var oModel = new sap.ui.model.odata.v2.ODataModel(BASE_HREF + 'odata/', {
//maxDataServiceVersion: '2.0',
json: true,
skipMetadataAnnotationParsing: true,
// those callbacks still do not get called at all
requestSent: function (a, b, c) {
debugger;
var trgrwg = oModel.getData();
var vfewgvfewgv = oModel.getProperty('/');
var vfewgvfewgv2 = oModel.getProperty('/rows');
var vfewgvfewgv3 = oModel.getProperty('rows');
},
requestFailed: function (a, b, c) {
debugger;
var trgrwg = oModel.getData();
var vfewgvfewgv = oModel.getProperty('/');
var vfewgvfewgv2 = oModel.getProperty('/rows');
var vfewgvfewgv3 = oModel.getProperty('rows');
},
requestCompleted: function (a, b, c) {
debugger;
var trgrwg = oModel.getData();
var vfewgvfewgv = oModel.getProperty('/');
var vfewgvfewgv2 = oModel.getProperty('/rows');
var vfewgvfewgv3 = oModel.getProperty('rows');
},
batchRequestCompleted: function (a, b, c) {
debugger;
var trgrwg = oModel.getData();
var vfewgvfewgv = oModel.getProperty('/');
var vfewgvfewgv2 = oModel.getProperty('/rows');
var vfewgvfewgv3 = oModel.getProperty('rows');
},
useBatch : false
});
The whole drama is that SapUI5 runs a request for $metadata, before making the actual request to odata/Contragents and so on. As expected in this case, I see in Fiddler, that the server 404-s to that request: http://localhost:55714/odata/Contragents/$metadata and it doesn't reach the moment to make the request to Contragents. I know, that I will have to change the source of the library somewhere in order to prevent this $metadata request from running, which I don't want to do. So in Fiddler's Composer, I tried the following: localhost:55714/odata/$metadata and it returned some xml with the desired metadata (maybe indeed it is important, but I haven't understood yet why). Next step was to modify the call to sap.ui.model.odata.v2.ODataModel(); as shown above. The great thing after all that is the fact, that oModel.read('/Contragents', {...}); showed signs of life! Now, the success callback gets called and in event.root I get those contragents as json string. And then what? I tried oModel.setData(JSON.parse(event.root)); but it gave me this error:
Also, if I manage to get it working this way, I don't quite understand, will the CRUD methods of oModel work? oModel.setData()-ing is something familliar to me from the time when I was playing around with JSONModel():
oModel = new sap.ui.model.json.JSONModel();
oModel.setData(dataForGrid); // this works like a charm
But using JSONModel() means, that I cannot use the insert(), update()... methods of sap.ui.model.odata.v2.ODataModel(), because JSONModel(); does not provide us with them, which is normal, as long as I get dataForGrid via a standard $.ajax() call.
edit2: While debugging, I noticed, that the method ContragentsController.GetContragents(); gets called twice and in the console, I see this error message:
edit3: Following the good example for ODataService, I added a "selection" method to the controller like this:
// GET: odata/Contragents(5)
[EnableQuery]
public SingleResult<Contragent> GetContragents([FromODataUri] string key)
{
return SingleResult.Create(db.Contragent.Where(contragent => contragent.Code == key));
}
In Fiddler, it 404-s and does not get called at all no matter if i Compose it like this: http://localhost:55714/Contragents(2) or like this: http://localhost:55714/odata/Contragents(2)
Couple of minutes later, I've got couple of % progress. I looked even closer in the tutorial and I noticed something, which made me change the "selection" method to this:
// GET: odata/Contragents(5)
[EnableQuery]
public SingleResult<Contragent> Get([FromODataUri] string key)
{
return SingleResult.Create(db.Contragent.Where(contragent => contragent.Code == key));
}
Now, when I Compose this request: http://localhost:55714/odata/Contragents(2), it now does not 404, but does 406 Not Acceptable. I came across this error code some time ago and I didn't understand well what is the reason for it and how is it related to ODataServices.
I just reminded myself what does 406 mean and it turns out, that every method on the controller must return a json result as string. Because, SapUI5 sets Accept-Type to "application/json".

Regex TypeError: Cannot read property '1' of null

My datepicker regular expression is trying matches on a null aray. How do I fix it? Not sure what clazz should equal if the array is null. I'm thinking a simple if (matches[1]) { etc } but I'm not sure what to do if matches is null. Clazz is used elsewhere twice in the code. Do I just set clazz to null or zero?
var matches = exp.match(IS_REGEXP);
var clazz = scope.$eval(matches[1]);
Edit: Here's where they use clazz
if (data.lastActivated !== newActivated) {
if (data.lastActivated) {
$animate.removeClass(data.lastActivated.element, clazz);
}
if (newActivated) {
$animate.addClass(newActivated.element, clazz);
}
data.lastActivated = newActivated;
}
Here's IS_REGEXP
11111111 22222222
var IS_REGEXP = /^\s*([\s\S]+?)\s+for\s+([\s\S]+?)\s*$/;
Double Edit:
Here's the whole function
function addForExp(exp, scope) {
var matches = exp.match(IS_REGEXP);
var clazz = scope.$eval(matches[1]);
var compareWithExp = matches[2];
var data = expToData[exp];
if (!data) {
var watchFn = function(compareWithVal) {
var newActivated = null;
instances.some(function(instance) {
var thisVal = instance.scope.$eval(onExp);
if (thisVal === compareWithVal) {
newActivated = instance;
return true;
}
});
if (data.lastActivated !== newActivated) {
if (data.lastActivated) {
$animate.removeClass(data.lastActivated.element, clazz);
}
if (newActivated) {
$animate.addClass(newActivated.element, clazz);
}
data.lastActivated = newActivated;
}
};
expToData[exp] = data = {
lastActivated: null,
scope: scope,
watchFn: watchFn,
compareWithExp: compareWithExp,
watcher: scope.$watch(compareWithExp, watchFn)
};
}
data.watchFn(scope.$eval(compareWithExp));
}
Setting clazz to null or empty string shall do, if clazz is all your concern.
var clazz = matches ? scope.$eval(matches[1]) : '';
But with compareWithExp, it might be better to exit from the whole logic when there is no match:
if ( ! matches ) return;

How to import entities after save changes with breeze across two entity managers

I've implemented repository pattern with two entity managers,
mainManager is for read only and delete, and updateManager is used for edit and add new entities. I use createEmptyCopy() to create updateManager.
Before i update an entity i export the entity from mainManager and import into the updateManager, after the change i call to updateManager.saveChanges() method.
I've noticed that i get back the updated entities in the promise response. i wonder what is the best practice to import those entities back into the mainManager?
here is my code:
function ($q, $http, entityManagerFactory) {
var self = this;
self.mainManager = entityManagerFactory.newManager();
self.updateManager = entityManagerFactory.newManager();
self.saveChanges = function () {
return self.updateManager.saveChanges();
};
self.rejectChanges = function() {
self.updateManager.rejectChanges();
};
self.getDomains = function () {
self.mainManager.clear();
var query = new breeze.EntityQuery()
.from('Domains')
.orderBy('name');
return self.mainManager.executeQuery(query);
};
self.createEmptyDomain = function () {
var domain = self.updateManager.createEntity('Domain');
return domain;
};
self.editDomain = function(domain) {
var exported = self.mainManager.exportEntities([domain]);
return self.updateManager.importEntities(exported).entities[0];
}
self.addDomain = function (domain) {
self.updateManager.addEntity(domain);
return self.updateManager.saveChanges();
};
self.deleteDomain = function (domain) {
domain.entityAspect.setDeleted();
var deferred = $q.defer();
self.mainManager.saveChanges().then(
function(data) {
deferred.resolve(data);
},
function (reason) {
console.log(reason);
self.mainManager.rejectChanges();
deferred.reject(reason);
});
return deferred.promise;
};
}
Right now i'm calling mainManager.clear() and get the data again from the server as you can see above in getDomains function.
But i think this is too expansive, why call the server if i already have the updated entities from the saveChanges promise?
i've also tried to import those entities back to mainManager using:
mainManager.importEntities(data.entities, { mergeStrategy: breeze.MergeStrategy.OverwriteChanges });
but i get an internal null breeze exception:
TypeError: Cannot read property 'forEach' of undefined
at EntityManager.proto.importEntities (breeze.debug.js:13081)
at self.importEntities (domain-list.service.js:22)
at domain-list.controller.js:70
at processQueue (angular.js:13170)
at angular.js:13186
at Scope.promises.$get.Scope.$eval (angular.js:14383)
at Scope.promises.$get.Scope.$digest (angular.js:14199)
at Scope.promises.$get.Scope.$apply (angular.js:14488)
at done (angular.js:9646)
at completeRequest (angular.js:9836)
the error is from this line breeze.debug.js:13081
13080: var tempKeyMap = {};
13081: json.tempKeys.forEach(function (k) {
13082: var oldKey = EntityKey.fromJSON(k, that.metadataStore);
13083: // try to use oldKey if not already used in this keyGenerator. 13084: tempKeyMap[oldKey.toString()] = new EntityKey(oldKey.entityType,
13085: that.keyGenerator.generateTempKeyValue(oldKey.entityType, oldKey.values[0]));
13086: });
var exportData = updateManager.exportEntities(data.entities, false);
mainManager.importEntities(exportData,
{ mergeStrategy: breeze.MergeStrategy.OverwriteChanges });

knockout viewModel ko.computed value not a function

I’m trying to update a computed knockout value using ko.compute on my current productsList observableArray and my "imageUrl". I keep getting undefined or ImageGalleryId is not a function when I try to get the value.
var productModel = function () {
var self = this;
window.viewModel = self;
self.productsList = ko.observableArray([]);
// I would like to get the image url for the current product
self.productsList.ImageUrl = ko.computed(function () {
// returns undefined
// var imageId = self.productsList.ImageGalleryId;
// returns: self.productsList.ImageGalleryId is not a function
// var imageId = self.productsList.ImageGalleryId();
// Need help **here**
var imageId = self.productsList.ImageGalleryId();
var imagePath = "/Image/GetImage/";
var imageSize = "/175/175/";
var url = imagePath + imageId + imageSize;
//console.log(url);
return url;
},self); // end ImageUrl
// Load data when model is created
self.dummyCompute = ko.computed(function () {
// start dummyCompute
//ajax call omitted
var JSONdataFromServer = {
"productsList":[
{
"ProductId":1,
"Title":"Product Name",
"ImageGalleryId":10,
"ImageUrl":"http://example.com"
},
{
"ProductId":2,
"Title":"Product Name",
"ImageGalleryId":11,
"ImageUrl":"http://example.com"
}
]};
self.productsList(JSONdataFromServer.productsList);
}, self); // end dummyCompute
};
ko.applyBindings(new productModel());
Fiddle code:
http://jsfiddle.net/Y8yT6/2/
productsList is an array, but you're treating it as if it were an object. I assume that you're really trying to deal with the properties of some specific member of the array, but there's nothing in your computed that tells it which one is the "current" product.
Once you get that resolved, you want ProductId without any parentheses, since it's a plain value and not an observable.

Resources