So when we browserify modules, it spits out this mysterious function:
(function e(t,n,r){
function s(o,u){
if(!n[o]){
if(!t[o]){
var a=typeof require=="function"&&require;
if(!u&&a)return a(o,!0);
if(i)return i(o,!0);
var f=new Error("Cannot find module '"+o+"'");
throw f.code="MODULE_NOT_FOUND",f
}
var l=n[o]={exports:{}};
t[o][0].call(l.exports,function(e){
var n=t[o][1][e];
return s(n?n:e)
},l,l.exports,e,t,n,r)
}
return n[o].exports
}
var i=typeof require=="function"&&require;
for(var o=0;o<r.length;o++)s(r[o]);
return s
})({
1:[function(require,module,exports){....
Now I've been looking all over for a source, explanation or one with readable variables but couldn't find it.
For example:
var a=typeof require=="function"&&require;
It seems that here the require() function is created, How is this defining it?
It's mainly the fact these variables are not readable, am I wrong to assume the following?
(function e(require,module,exports){
function s(o,u){
if(!module[o]){
if(!require[o]){
var a=typeof require=="function"&&require;
if(!u&&a)return a(o,!0);
if(i)return i(o,!0);
var f=new Error("Cannot find module '"+o+"'");
throw f.code="MODULE_NOT_FOUND",f
}
var l=module[o]={exports:{}};
require[o][0].call(l.exports,function(e){
var module = require[o][1][e];
return s(module ? module : e)
},l , l.exports, e, require, module, exports)
}
return module[o].exports
}
var i=typeof require=="function"&&require;
for(var o=0; o<exports.length; o++) s(exports[o]);
return s
})({
1:[function(require,module,exports){...
But that still leaves the s(o,u), which takes 2 arguments, but the only time that it is invoked, only gets 1 arg..
},l , l.exports, e, require, module, exports)
Where does that belong to?
Can anyone help fill in the blanks?
Stop looking, here is commented source file ;)
https://github.com/substack/browser-pack/blob/master/prelude.js
Related
I want to use Frida to add a class method to the existing Objective C class on Mac OS. After I read the Frida docs, I tried the following code:
const NSString = ObjC.classes.NSString
function func (n) { console.log(n) }
var nativeCb = new NativeCallback(func, 'void', ['int'])
ObjC.api.class_addMethod(
NSString.handle,
ObjC.selector('onTest:'),
nativeCb,
ObjC.api.method_getTypeEncoding(nativeCb)
)
The above code looks straightforward. However, after the ObjC.api.class_addMethod() call, the attached App and the Frida REPL both froze, it looks that the pointers are not right.
I have tried many possible parameter values for a whole night but still can figure the problem out. What's wrong with my code?
Only two issues:
method_getTypeEncoding() can only be called on a Method, which the NativeCallback is not. You could pass it the handle of an existing Objective-C method that has the same signature as the one you're adding, or use Memory.allocUtf8String() to specify your own signature from scratch.
Objective-C methods, at the C ABI level, have two implicit arguments preceding the method's arguments. These are:
self: The class/instance the method is being invoked on.
_cmd: The selector.
Here's a complete example in TypeScript:
const { NSAutoreleasePool, NSString } = ObjC.classes;
const onTest = new NativeCallback(onTestImpl, "void", ["pointer", "pointer", "int"]);
function onTestImpl(selfHandle: NativePointer, cmd: NativePointer, n: number): void {
const self = new ObjC.Object(selfHandle);
console.log(`-[NSString onTestImpl]\n\tself="${self.toString()}"\n\tn=${n}`);
}
function register(): void {
ObjC.api.class_addMethod(
NSString,
ObjC.selector("onTest:"),
onTest,
Memory.allocUtf8String("v#:i"));
}
function test(): void {
const pool = NSAutoreleasePool.alloc().init();
try {
const s = NSString.stringWithUTF8String_(Memory.allocUtf8String("yo"));
s.onTest_(42);
} finally {
pool.release();
}
}
function exposeToRepl(): void {
const g = global as any;
g.register = register;
g.test = test;
}
exposeToRepl();
You can paste it into https://github.com/oleavr/frida-agent-example, and then with one terminal running npm run watch you can load it into a running app using the REPL: frida -n Telegram -l _agent.js. From the REPL you can then call register() to plug in the new method, and test() to take it for a spin.
I am reading vuejs source code, and got confused by these two lines of code:
const args = toArray(arguments, 1)
args.unshift(this)
in the following snippet, why bother do this ?
/* #flow */
import { toArray } from '../util/index'
export function initUse (Vue: GlobalAPI) {
Vue.use = function (plugin: Function | Object) {
/* istanbul ignore if */
if (plugin.installed) {
return
}
// additional parameters
const args = toArray(arguments, 1)
args.unshift(this)
if (typeof plugin.install === 'function') {
plugin.install.apply(plugin, args)
} else {
plugin.apply(null, args)
}
plugin.installed = true
return this
}
}
Since you are inside of a Vueinstance, the lines in question are in the function defined on Vue.use the this most likely will reference the current Vue instance.
You will have to browse the source of toArray to understand the first line, it might takes the arguments and returning an array from them, and maybe substracting the first argument (the 1 in toArray(arguments, 1) give me this impression but to be sure browse the source of that function).
But then when the call args.unshift(this)comes it puts the Vue instance as the first element of the args array which is then used to provide arguments to the plugin function.
Hope that helps ;-)
Seb
In my TypeScript project (using only internal modules), I want to include polyfills/extension for an existing library. For this example, I will use the RxJS library but the question/problem is not specific to this library.
The following code is what I came up with:
module MyModule.Rx {
Rx.Observable.prototype.myExtension = function() { /* ... */ };
}
The RxJS definitions (.d.ts files) are used and compiled together with the code. This leads to the following compiler error: 2339 Property 'Observable' does not exist on type 'typeof Rx'
As far as I can tell this happens because I used the same Rx identifier in MyModule.Rx. When switching the namespace in the first line to module MyModule.NotRx { everything works fine - the Observable type is correctly looked up from the RxJS .d.ts file.
So it seems that the names MyModule.Rx and the RxJS declared Rx namespaces are in conflict. I know that I could simply rename my namespace to MyModule.SomethingElse but that seems somewhat of a hack.
Having all polyfills/extensions for Rx in the MyModue.Rx namespace seems a natural choice for me - how can this be done in a clean way?
You can't do that.
Take this code in TypeScript:
var B = 'test';
module A.B {
// Declare a function
export function fn() {
}
// Tests
console.log(B); // Object { }
A.B.fn(); // valid
B.fn(); // valid
fn(); // valid
}
The message displayed in the console is: Object { } and not test. Look at the transpiled code:
var B = 'test'; // root scope
var A;
(function (A) {
var B; // same name, hide the root scope one
(function (B) {
// Declare a function
function fn() {
}
B.fn = fn;
// Tests
console.log(B); // Object { }
A.B.fn(); // valid
B.fn(); // valid
fn(); // valid
})(B = A.B || (A.B = {}));
})(A || (A = {}));
The module A.B is transpiled to two JavaScript variables A and B. We can use them in order to access to the exported members of the module: the function fn is accessible from A.B.fn, B.fn and fn. In the module, the variable B from the root scope is hidden by the variable B of the module.
You can't access to a global variable Rx from a module named Rx.
As mentioned by Tarh you cannot refer to an outer module if its been shadowed by a local variable. I've +1ed his answer and that should be the accepted answer. I'll just leave a few workarounds:
One workaround which you already know is to rename MyModule.Rx to something that doesn't have Rx. An alternative is to capture Rx with some other name:
import OrigRx = Rx;
module MyModule.Rx {
OrigRx.Observable.prototype.myExtension = function() { /* ... */ };
}
This is very similar to https://stackoverflow.com/a/29021964/390330
I have created Dojo widget like below using AMD loader in Dojo 1.7.2
var myCpane;
require([
"dijit/layout/ContentPane"
], function(ContentPane) {
myCpane = new ContentPane();
});
myCpane.startup(); // It gives 'myCpane' as undefined
In the above example, in the last statment, the variable 'myCpane' is coming as 'undefined', if I use the 'myCpane.startup()' inside the 'require()' callback function then, it will work fine.
But I want to use that 'myCpane' variable on outside of the 'require' function (for many reasons). I know the 'require()' callback function execution delayed due to the component loading process by Dojo.
My question is,
How to block the 'require()' function until it completes to execute it's callback function.
So the variable 'myCpane' will not be 'undefined' when the control come out from the 'require()' function
===========================================================
To overcome this issue, I have written a small function to load the modules and wait until the module load complete
LoadModule: function(modulePath) { // modulePath = "dijit/layout/ContentPane"
var moduleObject = undefined;
require({async: false}, [modulePath], function(getModuleObject) {
moduleObject = getModuleObject;
});
// Wait until the module loads completes
while(moduleObject === undefined);
// Return the loaded module.
return moduleObject;
}
The output of the function is always executing the while loop, the control never comes inside of 'require()'s callback function to set the value to the variable "moduleObject".
When the 'require()' function will call it's callback function? I have verified using the browser debugger window the file 'ContentPane.js' is loaded properly, but the callback function is not called, If I comment the while loop then, the callback is called properly.
When the control will come inside of the callback function in my case ?
I'm not sure what are you about to achieve, but it looks for me like a programming anti-pattern. Anyway you can achieve this via dojo/_base/Deferred:
require(["dojo/_base/Deferred"], function(Deferred) {
var deferred = new Deferred();
require(["dijit/layout/ContentPane"], function(ContentPane) {
var myCpane = new ContentPane();
deferred.resolve(myCpane); //resolve, i.e. call `then` callback
});
deferred.then(function(myCpane) {
console.log(myCpane);
myCpane.startup();
});
});
Mess with it at jsFiddle: http://jsfiddle.net/phusick/HYQEd/
I would also suggest you consider one of these two strategies to achieve the same:
Give the ContentPane an id and obtain its reference via dijit's registry.byId().
Create ContentPane instance in a separate module and expose it as a return value of that module:
// file: myCpane.js
define(["dijit/layout/ContentPane"], function(ContentPane) {
var myCpane = new ContentPane();
return myCpane;
});
// file: main.js
require(["./myCpane"], function(myCpane) {
myCpane.startup();
});
I think this goes more to scope issue then amd loader question; consider
var x;
function foo() {
x = { bar : 1 };
}
// you wouldn't expect to have reference to x variable here
if(typeof x.bar == "undefined") console.log(x);
// foo() is called at a random time - or in dojo loader case, when modules are present
foo();
console.log(x.bar); // oohh now its there ^^
x in this case translates to your myCpane, which is declared as variable (var $$) inside a function, the function that is callback for when loader is done requireing modules.
The Deferred is a nice handler for this as stated below. A slight overhead though, if youre allready in a detached (async) function flow. For full control, look into require() you could do this as well:
var myCpane;
require({ async: false }, [
"dijit/layout/ContentPane"
], function(ContentPane) {
myCpane = new ContentPane();
});
// require does not return until module loading is done and callback executed
myCpane.startup();
How can i call a function form a variable.
var upfunction = init;
//or
var upfunction = init();
I have tried the above code and it does not work. I want to be able to call that variable from a keypress and change the variables function. For example.
function init(){
//Do whatever
}
function init2(){
//Do another thing
}
var upfunction = init();
if (Key.getCode() == Key.UP)
{
upfunction;
}
Then later doing
upfunction = init2();
That way i could change the function without having much code. Sorry if this is a noob question but all i do is copy and paste code i have found.
You're almost right with what you've got... just remember that to call a function you need to include the brackets afterwards: 'upFuntion();'. Brackets are also needed when defining the function. The brackets will contain any function parameters.
But to refer to the function (such as when assigning it to a variable) you don't use the brackets: 'upFunction = init;'
So your example would look like this:
function init1():Void {
trace("hello this is init1");
}
function init2():Void {
trace("hey, this is init2");
}
var upFunction:Function = init1;//type declaration is optional but recommended
upFunction();// hello this is init1
upFunction = init2;
upFunction();//hey, this is init2