Mac OS X - CoreFoundation - Reading Dictionary Value - firefox-addon

I'm trying to help someone out, so I'm writing some ctypes to check if the workstation is locked.
I am succesfully getting this info but I am not able to read the value from the dictionary.
This code runs flawlessly uptill the point it comes where i need to convert the obtained value to a string. See the comment //read value I put in the comment what error its throwing.
Cu.import('resource://gre/modules/ctypes.jsm');
var lib = {
CoreGraphics: '/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics',
CoreFoundation: '/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation'
};
for (var l in lib) {
lib[l] = ctypes.open(lib[l]);
}
//start mactypes
var Boolean = ctypes.unsigned_char;
var UniChar = ctypes.jschar; // uint16 with automatic conversion
//end mactypes
//start CoreFoundationTypes
var CFTypeRef = ctypes.void_t.ptr;
var __CFString = new ctypes.StructType('__CFString');
var CFStringRef = __CFString.ptr;
var __CFAllocator = new ctypes.StructType('__CFAllocator');
var CFAllocatorRef = __CFAllocator.ptr;
var CFIndex = ctypes.long;
var CFRange = new ctypes.StructType('CFRange', [{location: CFIndex}, {length: CFIndex}]);
//end CoreFoundationTypes
//dictionary functionality
var __CFDictionary = new ctypes.StructType('__CFDictionary');
var CFDictionaryRef = __CFDictionary.ptr;
var CFDictionaryGetValue = lib.CoreFoundation.declare('CFDictionaryGetValue', ctypes.default_abi, ctypes.void_t.ptr/*returns CFTypeRef*/, CFDictionaryRef, ctypes.void_t.ptr/*CFStringRef*/);
//end dictionary functionality
//string functionality
var CFStringCreateWithCharacters = lib.CoreFoundation.declare('CFStringCreateWithCharacters', ctypes.default_abi, CFStringRef, CFAllocatorRef, UniChar.ptr, CFIndex);
var CFStringGetLength = lib.CoreFoundation.declare('CFStringGetLength', ctypes.default_abi, CFIndex, CFStringRef);
var CFStringGetCharacters = lib.CoreFoundation.declare('CFStringGetCharacters', ctypes.default_abi, ctypes.void_t, CFStringRef, CFRange, UniChar.ptr);
//end string functionality
//common declares
var CFRelease = lib.CoreFoundation.declare('CFRelease', ctypes.default_abi, ctypes.void_t, CFTypeRef);
function convertCFString(CFStr) { //CFStr is something like that is returned by `CFStringCreateWithCharacters` see: https://github.com/philikon/osxtypes/blob/b359c655b39e947d308163994f7cce94ca14d98f/README.txt#L20
//start from: https://github.com/philikon/osxtypes/blob/b359c655b39e947d308163994f7cce94ca14d98f/README.txt#L22
var length = CFStringGetLength(CFStr);
var chars = ctypes.jschar.array(length)()
CFStringGetCharacters(CFStr, CFRange(0, length), chars);
var back = chars.readString();
//end from: //start from: https://github.com/philikon/osxtypes/blob/b359c655b39e947d308163994f7cce94ca14d98f/README.txt#L22
return back;
}
function makeCFStr(input) { //input is just a js string so like `var input = 'blah';`
return CFStringCreateWithCharacters(null, input, input.length); //see: https://github.com/philikon/osxtypes/blob/b359c655b39e947d308163994f7cce94ca14d98f/README.txt#L20
}
//end common declares
var CGSessionCopyCurrentDictionary = lib.CoreGraphics.declare('CGSessionCopyCurrentDictionary', ctypes.default_abi, CFDictionaryRef);
var CGSessionDict = CGSessionCopyCurrentDictionary();
console.log(uneval(CGSessionDict));
var kCGSSessionOnConsoleKey_str = 'kCGSSessionOnConsoleKey';
var kCGSSessionOnConsoleKey = CFStringCreateWithCharacters(null, kCGSSessionOnConsoleKey_str, kCGSSessionOnConsoleKey_str.length); //works // i figured it should be a string because of: https://github.com/JuliaEichler/Mac_OSX_SDKs/blob/392649d7112884481a94b8cd1f601f3a5edae999/MacOSX10.6.sdk/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/Versions/A/Headers/CGSession.h#L38 here they are making CFSTR of a text string
var kCGSSessionOnConsoleKey_val = CFDictionaryGetValue(CGSessionDict, kCGSSessionOnConsoleKey);
console.log('kCGSSessionOnConsoleKey_val:', kCGSSessionOnConsoleKey_val, uneval(kCGSSessionOnConsoleKey_val)); //printing `"kCGSSessionOnConsoleKey_val:" CData { } "ctypes.voidptr_t(ctypes.UInt64("0x7fff7a13b7f0"))"`
if (kCGSSessionOnConsoleKey_val.isNull()) {
console.log('CFDictionaryGetValue isNull so the key is not present in the dictionary, I am guesing');
} else {
//read value
var kCGSSessionOnConsoleKey_val_str = convertCFString(kCGSSessionOnConsoleKey_val); //throwing `Exception: expected type pointer, got ctypes.voidptr_t(ctypes.UInt64("0x7fff7a13b7f0"))`
}
CFRelease(kCGSSessionOnConsoleKey); //do release on things made with CFStringCreateWithCharacters per https://github.com/philikon/osxtypes/blob/master/examples/content/iphoto.js#L89
for (var l in lib) {
lib[l].close();
}
So basically within this convertCFString there is a function CFStringGetLength which takes 1st argument of CFStringRef which is defined as new ctypes.void_t.ptr. I am running this on the return value of CFDictionaryGetValue, and the return value of this function is also ctypes.void_t.ptr, it just doesn't have a new in front of it.
Here is example of convertCFString (and thus CFStringGetLength) working:
var kCGSSessionOnConsoleKey_str = 'kCGSSessionOnConsoleKey';
var kCGSSessionOnConsoleKey = CFStringCreateWithCharacters(null, kCGSSessionOnConsoleKey_str, kCGSSessionOnConsoleKey_str.length);
var str = convertCFString(kCGSSessionOnConsoleKey);
console.log('str:', str);
I have tried casting it like this:
var casted = ctypes.cast(kCGSSessionOnConsoleKey_val, CFStringRef.ptr).contents;
This makes it look exactly like __CFString.ptr(ctypes.UInt64("0x7fff7a13b7f0")) but when I do a convertCFString on this it crashes firefox.

Figured it out, I was casting it wrong. Also it's a boolean value so I had to cast it to CFBooleanRef:
var casted = ctypes.cast(kCGSSessionOnConsoleKey_val, CFBooleanRef);
Solution is here: https://gist.github.com/Noitidart/03052979069adc80a00c

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.

templateService.Parse not able to parese Tuple used in view(MVC)

I am trying to parse a .cshtml with tuple and tuple used for acces two models in the view same time, but it is not working throwing error, but if I am using only one model than same this is wotking.
Here is my code:
Controller:
var deviceModel = new DevicesInformationDataViewModel { };
var eventModel = new EventsInformationDataViewModel{ };
var templateFolderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Views\\EmailTemplates");
var emailTemplatePath = Path.Combine(templateFolderPath, "EmailTemplates.cshtml");
var templateService = new TemplateService();
var emailHtmlBody = "";
string email = data[1];
ViewBag.info = data[0];
if (data[0] == "DeviceInfo")
{
deviceModel.Address = data[2];
deviceModel.Description = data[3];
deviceModel.eDescription = data[4];
deviceModel.Fault = data[5];
deviceModel.Type = data[6];
deviceModel.TypeCode = Int32.Parse(data[7]);
deviceModel.DriftCompensation = Int32.Parse(data[8]);
deviceModel.AlarmSensitivity = data[9];
deviceModel.Status = data[10];
emailHtmlBody = templateService.Parse(System.IO.File.ReadAllText(emailTemplatePath), deviceModel, ViewBag.info, null);
}
View:
If using like this, not working:
#model Tuple<DevicesInformationDataViewModel,EventsInformationDataViewModel>
but if using like this, it is working:
#model DevicesInformationDataViewModel
Can any body tell me what I am doing wrong and please tell me how can I resolve
this issue?

How to append key to an image's name asp.net mvc

Here is my code to append postfix to an image:
private void SaveUpload(SledBuck sledBuck )
{
if (Request.Files.Count > 0)
{
var postFix = "_" + sledBuck.Id;
for (var index = 0; index < Request.Files.Count; index++)
{
if (Request.Files[index].ContentLength > 0)
{
var hpf = Request.Files[index];
var postedFileName = string.Format("{0}-{1}", Path.GetFileName(hpf.FileName), postFix);
string folderPath = ConfigurationManager.AppSettings["ImagePath"];
var savedFileName = Path.Combine(Server.MapPath(folderPath), postedFileName);
hpf.SaveAs(savedFileName); // Save the file
}
}
}
}
Let's say the image's name is image.jpg. I want to append primary key to it's name before updating it like image_1.jpg. For the code above the postedFileName = image.jpg_1 which is not what I want. How can I append the Id properly?
so basically what you get as hpf.FileName is FileName + Extension. You need to get the extension and work accordingly,
so proceed like this :
var hpf = Request.Files[index];
var FileExtension = Path.GetExtension(hpf.FileName);
var FileNameWithoutExtension = hpf.FileName.Replace(FileExtension, "");
var FileUniqueName = String.Format("{0}_{1}{2}", FileNameWithoutExtension, GenerateDateTimeStamp(), FileExtension);
string folderPath = ConfigurationManager.AppSettings["ImagePath"];
var savedFileName = Path.Combine(Server.MapPath(folderPath), FileUniqueName);
hpf.SaveAs(savedFileName); // Save the file
where GenerateDateTimeStamp() is
public string GenerateDateTimeStamp()
{
return DateTime.Now.ToString("ddmmyyyyMMhhssttt");
}
in here you can have your primary keys aswell.
this should give you some idea

Get text from textarea

I feel like I am going insane trying to get the most simple of things to work! I have a mailing list in Google Spreadsheet on Google Drive. I have created a user interface that prompts for the message that the user wants to include in the email. My code looks like this.
function startBulkEmailUI(e) {
//create main form
var app = UiApp.createApplication().setTitle('Send Email').setWidth(602).setHeight(402);
var scrollPanel = app.createScrollPanel().setId('scrollPanel').setAlwaysShowScrollBars(true) ;
var mainPanel = app.createVerticalPanel().setId('mainPanel');
mainPanel.setStyleAttribute('border', '1px solid #C0C0C0').setWidth("100%").setHeight("100%");
scrollPanel.add(mainPanel);
//create panel for input boxes etc
var inputPanel = app.createVerticalPanel().setId('inputPanel').setWidth("100%").setHeight("100%").setSpacing(0);
var messageLabel = app.createLabel('E-mail Message');
var messageBox = app.createTextArea().setName('messageBox').setId('messageBox').setVisible(true).setWidth(400).setHeight(150);
var attachmentLabel = app.createLabel('E-mail Attachment');
var attachmentCheckBox = app.createCheckBox('Attach a file').setValue(false);
inputPanel.add(messageLabel).add(messageBox).add(attachmentLabel).add(attachmentCheckBox);
mainPanel.add(inputPanel).setCellHorizontalAlignment(inputPanel, UiApp.HorizontalAlignment.CENTER) ;
inputPanel.setCellHorizontalAlignment(messageLabel, UiApp.HorizontalAlignment.CENTER);
inputPanel.setCellHorizontalAlignment(messageBox, UiApp.HorizontalAlignment.CENTER);
inputPanel.setCellHorizontalAlignment(attachmentLabel, UiApp.HorizontalAlignment.CENTER);
inputPanel.setCellHorizontalAlignment(attachmentCheckBox, UiApp.HorizontalAlignment.CENTER);
//add function buttons
var buttonsPanel = app.createHorizontalPanel().setStyleAttribute('margin', '20px').setWidth(500);
var closeButton = app.createButton('Close',app.createServerHandler('close_'));
var sendButton = app.createButton('Send!').setId("sendButton");
buttonsPanel.setId('buttonsPanel').add(closeButton).add(sendButton);
mainPanel.add(buttonsPanel).setCellHorizontalAlignment(buttonsPanel, UiApp.HorizontalAlignment.CENTER);
buttonsPanel.setCellHorizontalAlignment(closeButton, UiApp.HorizontalAlignment.CENTER).setCellHorizontalAlignment(sendButton, UiApp.HorizontalAlignment.CENTER);
app.add(scrollPanel);
//handlers
var handlerSendEmails = app.createServerClickHandler('sendEmails');
handlerSendEmails.addCallbackElement(inputPanel);
sendButton.addClickHandler(handlerSendEmails);
//show the form
ss.show(app);
return app;
}
function sendEmails(e) {
var contactDetail = getContactDetail();
var count = 0;
var failed = 0;
for (i in contactDetail) {
var row = contactDetail[i];
var emailAddress = row[9];
var stuff = e.parameter.messageBox.value;
Logger.log(e.parameter);
var message = 'Hi, ' + row[4] + '\n\n' + 'This is a test!'; // Second column
var subject = 'Test Email';
try {
// MailApp.sendEmail(emailAddress, subject, message);
count = count+1;
} catch(e) {
failed = failed+1;
}
}
var msg = stuff;
Browser.msgBox('Debug Msg', msg, Browser.Buttons.OK);
}
I want the user to enter information into the textarea, which I can then use as the body of an email. I discovered there is no getText, so I have found hundreds of answer saying it should look like the code above: you create a callbackhandler, then use e.parameter.OBJECT_NAME.value to get the text. It simply does not work for me and I have tried every workaround that I can think of. Any suggestions? Is my code faulty (I know it's messy...)?
The "normal" way to get a widget's value in a handler function is in the form e.parameter.widgetName so in you case you should simply use
var stuff = e.parameter.messageBox; without the ".value" , the result is a string.

An observer for page loads in a custom xul:browser

In my firefox extension I'm creating a xul:browser element. I want to have an observer that intercepts any url changes within the embedded browser and opens the url in a new browser tab (in the main browser). I'd also like new windows spawned by the xul:browser window to open in a tab instead of a new browser window.
I've created an observer which works, but I don't yet know how to apply that observer only to the xul:browser element.
function myFunction(){
var container = jQuery("#container")[0];
var new_browser_element = document.createElement('browser');
container.appendChild(new_browser_element);
var observerService = Components.classes["#mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
observerService.addObserver(myObserver, "http-on-modify-request", false);
}
var myObserver = {
observe: function(aSubject, aTopic, aData){
if (aTopic != 'http-on-modify-request'){
aSubject.QueryInterface(Components.interfaces.nsIHttpChannel);
// alert(aSubject.URI.spec);
// Now open url in new tab
}
},
QueryInterface: function(iid){
if (!iid.equals(Components.interfaces.nsISupports) &&
!iid.equals(Components.interfaces.nsIObserver))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
}
};
You could try:
var myObserver = {
observe: function(aSubject, aTopic, aData){
if (aTopic == 'http-on-modify-request')
{
aSubject.QueryInterface(Components.interfaces.nsIHttpChannel);
var url = aSubject.URI.spec;
var postData ;
if (aSubject.requestMethod.toLowerCase() == "post")
{
var postText = this.readPostTextFromRequest(request);
if (postText)
{
var dataString = parseQuery(postText);
postData = postDataFromString(dataString);
}
}
var oHttp = aSubject.QueryInterface(Components.interfaces.nsIHttpChannel);
var interfaceRequestor = oHttp.notificationCallbacks.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
var DOMWindow = interfaceRequestor.getInterface(Components.interfaces.nsIDOMWindow);
//check if it is one of your mini browser windows
if (jQuery(DOMWindow).hasClass('mini_browser'))
{
openInTab(url, postData);
var request = aSubject.QueryInterface(Components.interfaces.nsIRequest);
request.cancel(Components.results.NS_BINDING_ABORTED);
}
}
},
QueryInterface: function(iid){
if (!iid.equals(Components.interfaces.nsISupports) &&
!iid.equals(Components.interfaces.nsIObserver))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
},
readPostTextFromRequest : function(request) {
var is = request.QueryInterface(Components.interfaces.nsIUploadChannel).uploadStream;
if (is)
{
var ss = is.QueryInterface(Components.interfaces.nsISeekableStream);
var prevOffset;
if (ss)
{
prevOffset = ss.tell();
ss.seek(Components.interfaces.nsISeekableStream.NS_SEEK_SET, 0);
}
// Read data from the stream..
var charset = "UTF-8";
var text = this.readFromStream(is, charset, true);
// Seek locks the file so, seek to the beginning only if necko hasn't read it yet,
// since necko doesn't seek to 0 before reading (at lest not till 459384 is fixed).
if (ss && prevOffset == 0)
ss.seek(Components.interfaces.nsISeekableStream.NS_SEEK_SET, 0);
return text;
}
else {
dump("Failed to Query Interface for upload stream.\n");
}
}
return null;
},
readFromStream : function(stream, charset, noClose)
{
var sis = Components.classes["#mozilla.org/binaryinputstream;1"]
.getService(Components.interfaces.nsIBinaryInputStream);
sis.setInputStream(stream);
var segments = [];
for (var count = stream.available(); count; count = stream.available())
segments.push(sis.readBytes(count));
if (!noClose)
sis.close();
var text = segments.join("");
return text;
}
};
function openInTab(url, postData)
{
var wm = Components.classes["#mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
var recentWindow = wm.getMostRecentWindow("navigator:browser");
if (recentWindow)
{
// Use an existing browser window, open tab and "select" it
recentWindow.gBrowser.selectedTab = recentWindow.gBrowser.addTab(url, null, null, postData);
}
}
function parseQuery() {
var qry = this;
var rex = /[?&]?([^=]+)(?:=([^&#]*))?/g;
var qmatch, key;
var paramValues = {};
// parse querystring storing key/values in the ParamValues associative array
while (qmatch = rex.exec(qry)) {
key = decodeURIComponent(qmatch[1]);// get decoded key
val = decodeURIComponent(qmatch[2]);// get decoded value
paramValues[key] = val;
}
return paramValues;
}
function postDataFromString(dataString)
{
// POST method requests must wrap the encoded text in a MIME
// stream
var stringStream = Components.classes["#mozilla.org/io/string-input-stream;1"]
.createInstance(Components.interfaces.nsIStringInputStream);
if ("data" in stringStream) // Gecko 1.9 or newer
stringStream.data = dataString;
else // 1.8 or older
stringStream.setData(dataString, dataString.length);
var postData = Components.classes["#mozilla.org/network/mime-input-stream;1"].
createInstance(Components.interfaces.nsIMIMEInputStream);
postData.addHeader("Content-Type", "application/x-www-form-urlencoded");
postData.addContentLength = true;
postData.setData(stringStream);
return postData;
}
I'll update this to fill in the blanks in a bit.
edit: see http://forums.mozillazine.org/viewtopic.php?p=2772951#p2772951 for how to get the source window of a request.
Request cancellation code from http://zenit.senecac.on.ca/wiki/index.php/Support_For_OpenID.
see http://mxr.mozilla.org/mozilla-central/source/netwerk/base/public/nsIRequest.idl for details on nsIRequest.
See http://forums.mozillazine.org/viewtopic.php?p=2404533#p2404533 and https://developer.mozilla.org/en/XUL/Method/addTab for the definition of addTab.
parseQuery comes from http://blog.strictly-software.com/2008/10/using-javascript-to-parse-querystring.html.
See https://developer.mozilla.org/en/Code_snippets/Post_data_to_window#Preprocessing_POST_data for how to process post data in a form suitable for addTab.
ReadPostFromText and ReadTextFromStream both come from firebug (though slightly modified)

Resources