1.什么叫原码、源码反码、源码补码、源码和原码、源码反码、源码补码
2.与非门怎样实现四输入与非?
3.请问这种JS代码怎么加密
4.Hermes源码分析(二)——解析字节码
什么叫原码、源码私密博客源码反码、源码补码、源码和原码、源码反码、源码补码
正数的源码原码、反码、源码补码相同;
负数的源码原码取反就是反码(最高位1不能变),反码+1就是源码怎么编译sp源码补码;
负数的补码取反就是反码(最高位1不能变),反码+1就是源码原码;
因为最高bit不是1,所以这里Y一定是正整数。
如果X是无符号数:
X和Y的补码就是源码,直接相减的到结果是整数,也是补码,
X-Y=
如果X是有符号数:
X的原码是,即-,Y的原码是,即,X-Y为-,得到的原码,对应的补码是
与非门怎样实现四输入与非?
如果只有LS芯片,可以通过级联两个与非门实现四输入的文化网站 源码与非逻辑关系。具体实现方法如下:将四个输入信号分别连接到两个与非门的输入端口上,其中两个信号连接到第一个与非门的一组输入端口上,另外两个信号连接到第二个与非门的一组输入端口上。
将第一个与非门的输出端口连接到第二个与非门的一个输入端口上。
将第二个与非门的输出端口作为最终的输出信号。
这种方法可以实现四个输入信号的与非逻辑关系,其中第一个与非门起到“或”逻辑的作用,将两个输入信号合并成一个中间信号;第二个与非门起到“非”逻辑的作用,将中间信号取反得到最终的输出信号。
请问这种JS代码怎么加密
这不算加密,只不过一眼看不出来罢了。其实就是JavaScript字符串转义。原理很简单,js语音播报源码比如字符 ’w‘
它的 charCode 是 十六进制表示为 0x
然后利用 JavaScript 字符串转义前缀 \x,表达出编码过的 ASCII 字符来:
\x + charCode的十六进制表示(两位)所以字符串 '\x' 就是字符串 'w'
也就是说
'\x' === 'w'这个的返回值是 true,二者完全等效!
这是对于 ascii 代码表示形式,charCode 大于 的怎么处理?就要用到 \u 前缀了
\u + charCode的十六进制表示(比如汉字 '学' 的 charCode 是 (0x5b)
书写时只要把 0x 替换为 \u:
\u5b这样就可以了。
'\u5b' === '学'那么为什么要这么麻烦呢?直接输入字符不就好了吗?要知道,有些字符是不能打印或不能被输入的(比如功能/控制字符“退格”等),如果要在字符串中包含这些字符,只能依靠字符串转义了!
回头看楼主给的代码:
"\x\x6f\x\x\x6d\x\x6e\x"这个是什么?
F开浏览器开发者工具,切到控制台(或者你有 node.js),在控制台输入这一串。
你看到输出什么了吗?
"document"继续
"\x\x\x\x\x\x6c\x6e"这个输入后,http请求源码解读控制台返回
"writeln"剩下括号内的也是一样的啦。结果是一个指向特定地址的 <a> 标签。
所以翻译过来就是
window['document']['writeln']('<a href="...">标签</a>')看懂了?
好,既然楼主说要怎么加密的。我就写了个 JS 脚本,只要调用这个方法,你就得到“加密”后的字符串信息了:
function encrypt(str) {var result = '', charCode
for(var i = 0, length = str.length; i < length; i++) {
charCode = str.charCodeAt(i)
if(charCode < 0x) {
result += '\\x0' + charCode.toString()
} else if(charCode < 0x) {
result += '\\x' + charCode.toString()
} else if(charCode < 0x) {
result += '\\u0' + charCode.toString()
}else {
result += '\\u' + charCode.toString()
}
}
return result
}
在控制台执行
encrpty('楼主给的那一串')返回
"\x3c\x\x\x\x\x\x\x3d\x\x\x\x\x\x3a\x2f\x2f\x\x\x\x2e\x\x\x\x6d\x6b\x2e\x\x6f\x6d\x2f\x\x\x\x\x\x\x\x\x3d\x\x5f\x\x6c\x\x6e\x6b\x\x\x\x\x\x6c\x\x3d\x\x\x6f\x6c\x6f\x\x3a\x\x\x\x\x\x\x\x3b\x\x3e\x3c\x\x3e\x\x\u6e\u\u8bba\ub\x3c\x2f\x\x3e\x3c\x2f\x\x3e"楼主只要把括号中的那一串替换为上面输入的内容就好了。
Hermes源码分析(二)——解析字节码
前面一节 讲到字节码序列化为二进制是有固定的格式的,这里我们分析一下源码里面是怎么处理的这里可以看到首先写入的是魔数,他的值为
对应的二进制见下图,注意是小端字节序
第二项是字节码的版本,笔者的版本是,也即 上图中的4a
第三项是源码的hash,这里采用的是SHA1算法,生成的哈希值是位,因此占用了个字节
第四项是文件长度,这个字段是位的,也就是下图中的为0aa,转换成十进制就是,实际文件大小也是这么多
后面的字段类似,就不一一分析了,头部所有字段的类型都可以在BytecodeFileHeader.h中看到,Hermes按照既定的内存布局把字段写入后再序列化,就得到了我们看到的字节码文件。
这里写入的数据很多,以函数头的写入为例,我们调用了visitFunctionHeader方法,并通过byteCodeModule拿到函数的签名,将其写入函数表(存疑,在实际的文件中并没有看到这一部分)。注意这些数据必须按顺序写入,因为读出的时候也是按对应顺序来的。
我们知道react-native 在加载字节码的时候需要调用hermes的prepareJavaScript方法, 那这个方法做了些什么事呢?
这里做了两件事情:
1. 判断是否是字节码,如果是则调用createBCProviderFromBuffer,否则调用createBCProviderFromSrc,我们这里只关注createBCProviderFromBuffer
2.通过BCProviderFromBuffer的构造方法得到文件头和函数头的信息(populateFromBuffer方法),下面是这个方法的实现。
BytecodeFileFields的populateFromBuffer方法也是一个模版方法,注意这里调用populateFromBuffer方法的是一个 ConstBytecodeFileFields对象,他代表的是不可变的字节码字段。
细心的读者会发现这里也有visitFunctionHeaders方法, 这里主要为了复用visitBytecodeSegmentsInOrder的逻辑,把populator当作一个visitor来按顺序读取buffer的内容,并提前加载到BytecodeFileFields里面,以减少后面执行字节码时解析的时间。
Hermes引擎在读取了字节码之后会通过解析BytecodeFileHeader这个结构体中的字段来获取一些关键信息,例如bundle是否是字节码格式,是否包含了函数,字节码的版本是否匹配等。注意这里我们只是解析了头部,没有解析整个字节码,后面执行字节码时才会解析剩余的部分。
evaluatePreparedJavaScript这个方法,主要是调用了HermesRuntime的 runBytecode方法,这里hermesPrep时上一步解析头部时获取的BCProviderFromBuffer实例。
runBytecode这个方法比较长,主要做了几件事情:
这里说明一下,Domain是用于垃圾回收的运行时模块的代理, Domain被创建时是空的,并跟随着运行时模块进行传播, 在运行时模块的整个生命周期内都一直存在。在某个Domain下创建的所有函数都会保持着对这个Domain的强引用。当Domain被回收的时候,这个Domain下的所有函数都不能使用。
未完待续。。。