首页 > 其他分享 >aardio封装库) sunny抓包工具的使用

aardio封装库) sunny抓包工具的使用

时间:2024-03-25 09:33:45浏览次数:30  
标签:__ function 函数 aardio sunny messageId var 抓包 定义

前言

还有个迭代器,基础语法基本已经说完了,后面想到啥再补充,之后的教程会从以下方面来讲:

  • 基础库的使用,比如string、table等
  • 基础控件的使用,比如listview、tab等
  • aardio和Python交互,比如给Python写个界面
  • 自带的范例程序
  • 我写的一些小程序

当然,我的理解也是很基础的,特别是在界面设计上,我都是用的默认控件的默认设置,不会去自定义控件内容。要想做出特别炫酷的程序,你还得依赖其他语言和工具的基础。例如用HTML和CSS来实现界面。

元表、元方法

参考文档:

  • https://bbs.aardio.com/doc/reference/libraries/kernel/table/meta.html
  • https://bbs.aardio.com/doc/reference/the%20language/operator/overloading.html

主要是用于重载运算符和内置函数的行为。

表可以定义另一个表作为元表,然后在元表里定义元方法来定义操作符或内置函数操作表的一些行为。这种类似于Python的魔法方法,在Python中使用__eq__定义==的行为,而在aardio中用_eq元方法来定义==的行为。

初级使用例子

举个例子,python中print会调用对象的__str____repr__来打印一个对象,而aardio也是调用tostring来打印一个对象,但表默认并没有定义_tostring元方法,导致打印出来的内容是table: 03B2E3A8的格式

我们可以通过给表定义_tostring元方法,来使io.print或者console.log正常显示表

import console; 
io.open()
var tab = {
	a=1;
	b=2;
	@{
		_tostring = function(...) {
		    // 元方法里不能调用触发元方法的函数,比如_tostring里不能调用tostring
		    // _get元方法可以通过[[k]]运算符来避开元方法,通过.和[]会触发_get,而[[]]不会
			return table.tostring(owner);
		}
	}
}
io.print("没有定义元方法" , {});
io.print("定义了元方法" , tab);
console.pause(true);

输出如下:

没有定义元方法  table: 03A8E2F8
定义了元方法    {
a=1;
b=2
}

运算符重载

这个就不细说了,应该很容易理解。

io.open(); tab = { x=10 ; y=20 };
tab2 = { x=12 ; y=22 }
//c = tab + tab2; //这样肯定会出错,因为 table默认是不能相加的

//创建一个元素,元表中的__add函数重载加运算符。
tab@ = {
	_add = function(b) { 
		return owner.x + b.x
	};
}

c = tab + tab2; //这时候会调用重载的操作符 tab@._add(tab2)
io.print( c ) //显示22

入门使用例子

还有一个很常用的元方法是_get_set,是定义访问对象属性时触发的。利用这个可以让代码量少很多,看起来逻辑也更清晰。

这里举个实际例子,我在封装sunny的时候,遇到个很累人的事。sunny的dll导出函数,返回值有些是指针,你需要手动给他转成字符串,而且还需要手动释放这个指针指向的内存,也就是说你调用一次导出函数,就得写至少三行代码(调用、转字符串和释放)。

那么,有没有一种方法,定义完这个导出函数,在使用的时候就调用函数释放内存,并转成字符串返回,而不用我每次都手动释放和转字符串。

先定义request类,现在只需要给它定义一个messageId属性和_meta元方法:

namespace sunny;

class request{
	ctor(messageId){
		this.messageId = messageId;
	}
	@_meta;
	
}

@后面跟的是元表的名称,你可以将元表定义在名字空间里,这样看起来代码更舒服。下面在类的名字空间里定义dll方法和元表.

namespace request{
    //释放指针的函数
	Free = ::SunnyDLL.api("Free","void(pointer p)");
	// 下面的函数第一个参数都是messageId
    DelRequestHeader = ::SunnyDLL.api("DelRequestHeader","void(int id,str h)");
    GetRequestBodyLen = ::SunnyDLL.api("GetRequestBodyLen","int(int id)");
	GetRequestBody = ::SunnyDLL.api("GetRequestBody","pointer(int id)");
	// 定义一个中间方法
    // name是要调用的导出函数,messageId则是导出函数的第一个参数
	xcall = function(name, messageId, len){
		var func = self[name];
		if(!func) error("不支持的函数!");
		function proxyFunc(...){
			var v = func(messageId, ...);
			var result;
			if(type(v) == type.pointer){
				if(len) result = ..raw.tostring(v,1,len);
				else result = ..raw.tostring(v);
				Free(v);
			}else{
				result = v;
			}
			return result;
		}
		
		return proxyFunc;
	}
	// 定义元表
	_meta = {
		_get = function(k){
			return xcall(k, owner.messageId);
		}
		
	}
}

这个代码初看可能有点费劲,我们拆解着来看。

首先前面几行只是定义了四个dll的导出函数,然后下面定义了_meta这个表。

而_meta里只定义了一个元方法_get,它的作用是当你访问对象的属性时会触发这个方法,然后给你返回值。比如我先实例化一个request对象

r = request(111111);
// 当访问r.GetRequestBody时,这个对象没有GetRequestBody属性,所以会触发_get元方法
// 得到的返回值就是 返回它的返回值也就是`xcall("GetRequestBody", owner.messageId)`.
console.log(r.GetRequestBody)

这里的owner就是指r这个对象。然后定义了xcall这个函数,它里面又定义了一个函数proxyFunc,并将它作为返回值,这种被称为闭包。先分析下xcall方法

// 这里的self指的是当前名字空间,也就是request,name则是需要调用的方法名,例如是GetRequestBody
// 这里func的值就等于GetRequestBody,也就是::SunnyDLL.api("GetRequestBody","pointer(int id)");
var func = self[name];
// 如果func是null的话,说明当前名字空间下没有这个函数,也就不是我们定义的sunny导出函数
if(!func) error("不支持的函数!");
// 定义了proxyFunc函数,`xcall(k, owner.messageId)`返回的值就是proxyFunc函数,这里的三个点表示传入任意个参数,类似于Python中的*args
function proxyFunc(...){
    // 调用GetRequestBody(messageId, ...)
	var v = func(messageId, ...);
	// 定义返回结果
	var result;
	// 如果结果是指针的话
	if(type(v) == type.pointer){
	    // 就把它转为字符串,二进制数据需要指定长度,不然就是到\0结束
		if(len) result = ..raw.tostring(v,1,len);
		else result = ..raw.tostring(v);
		// 调用导出函数释放内存
		Free(v);
	}else{
	    // 如果是其他类型数据就直接返回,比如数值或null
		result = v;
	}
	return result;
}

这样一番折腾,起了什么效果呢,看一下下面两段代码,如果不利用元方法的话,你使用dll导出函数得这么写

// 导入request名字空间
improt request;
// 调用名字空间下的函数
var messageId = 111111
var pResult = request.GetRequestBody(messageId);
// 将指针转为字符串
var result = raw.tostring(pResult,1);
// 释放内存
request.Free(pResult);
// 再使用其他导出函数也需要重复写这几行代码

看着就几行代码,但是你想想调用一个函数都得写好几行,如果调用多次呢。而定义了xcall和_meta之后,只需要这样写代码:

improt request;
var messageId = 111111;
var req = request(messageId);
var result = req.GetRequestBody();
// 后面调用都只需要用req.方法名()调用,不需要管raw.tostring和Free了

因为req是可以复用的,所以我调用任何导出函数都只需要写一行代码,使用sunny库的代码也变得更简洁易懂了。

官方例子

给表创建一个代理,监控表属性的访问和设置:

// 创建一个代理,为另一个table对象创建一个替身以监控对这个对象的访问
function table.createProxy(tab) {
    var real = tab;//在闭包中保存被代理的数据表tab
    var _meta = {
        _get = function(k){
            io.print(k+"被读了");
            return real[k];
        };
        _set = function (k,v){
            io.print(k+"被修改值为"+v)
            real[k]=v; //删除这句代码就创建了一个只读表
        }
    }
    var proxy = {@_meta};//创建一个代理表
    
    return proxy; //你要访问真正的表?先问过我吧,我是他的经纪人!!!
}

//下面是使用示例

tab = {x=12;y=15};
proxy = table.createProxy(tab);//创建一个代理表,以管理对tab的存取访问

io.open();
c = proxy.x; //显示 "x被读了"
proxy.y = 19; //显示 "y被修改值为19"
io.print(proxy.y); //显示 "y被读了" 然后显示19

所有的元方法

元方法/属性 函数定义 Python中的魔法方法 说明
_weak 用不到
_type 属性 type(obj)函数的行为
_readonly 属性 等于false,_开头的成员也不是只读属性
_defined 感觉没啥用
_keys 属性 可用于table.keys等函数动态获取对象的键名列表(例如动态生成键值对的外部JS对象可使用这个元方法返回成员名字列表
_startIndex 属性 用于table.eachIndex等函数动态指定数组的开始下标。
_get function(k,ownerCall) __getattr____getitem__ 如果读取表中不存在的键会触发_get元方法并返回值
_set function(k,v) __setattr____setitem__ 当你给表的一个缺少的键赋值时会触发_set元方法
_tostring function(...) __str____repr__ tostring(obj, ...)
_tonumber function() tonumber(obj)
_json function() web.json.stringify(obj),可返回一个可被转化为json的值。或者返回一个字符串和true
_toComObject 用于自定义一个表对象如何转换为 COM 对象,可定义为函数,也可以直接定义为对象
_eq function(b) __eq____ne__ ==!=,比较对象时,两个对象的_eq必须是同一个
_le function(b) __le____ge__ <=>=
_lt function(b) __lt____gt__ <>
_add function(b) __add__ +
_sub function(b) __sub__ -
_mul function(b) __mul__ *
_div function(b) __truediv__ /
_lshift function(b) __lshift__ << 左移
_rshift function(b) __rshift__ >> 右移
_mod function(b) __mod__ % 取模
_pow function(b) __pow__ **幂运算
_unm function() __neg__ - 负号
_len function() __len__ #取长运算符,Python中则为len函数
_concat function(b) ++ 连接运算符
_call function(...) __call__ 对象当函数来调用

属性元表

不仅可以给对象定义元表,也可以给对象的属性定义一个元表,有点类似于Python中的property,可以控制属性修改和获取的行为。

如果要看例子的话,可以在aardio的目录全局搜下@_metaProperty

以使用最多的属性text为例,基本每个控件都有一个text属性,你可以很方便的通过.text获取和修改空间显示的文字。

其实不用属性元表也能实现这个效果,代码如下:

import console; 
class staticText{
	getText = function(){
		..console.log("获取到界面文本内容")
	};
	setText = function(v){
		..console.log("将文本("+v+")显示到界面控件上")
	}
	@_meta;
}

namespace staticText{
    _meta = {
        _get = function(k){
        	if(k == "text"){
        	    return owner.getText();
        	}
        };
        _set = function(k,v){
        	if(k == "text"){
        	    return owner.setText(v);
        	}
        }    
    }
}

s = staticText()
console.log(s.text);
s.text = "修改文本";
console.pause(true);

但是如果属性多了的话,就需要一堆的if来判断属性,所以aardio作者就引入了metaProperty这个功能。这样写的代码看起来更简洁和清晰,用法如下:

import console; 
import util.metaProperty;

class staticText{
	getText = function(){
		..console.log("获取到界面文本内容")
	};
	setText = function(v){
		..console.log("将文本("+v+")显示到界面控件上")
	}
	@_metaProperty;
}

namespace staticText{
    _metaProperty = ..util.metaProperty(
        text = {
            _get = function(){
            	return owner.getText();
            };
            _set = function(v){
            	return owner.setText(v);
            }
        };
        // 可以写其他属性
    );
    // 可以打印下_metaProperty看看
    ..console.dump(_metaProperty);
}

s = staticText()
console.log(s.text);
s.text = "修改文本";
console.pause(true);

本文由博客一文多发平台 OpenWrite 发布!

标签:__,function,函数,aardio,sunny,messageId,var,抓包,定义
From: https://www.cnblogs.com/kanadeblisst/p/18093690

相关文章

  • 主机存活探测方式及抓包分析
    前言       存活探测通常使用ICMP协议的Echo请求(ping)或TCP协议的SYN请求来实现。当发送一个Echo请求或SYN请求到目标主机时,如果目标主机在线并能够响应,它将返回一个Echo响应或SYN+ACK响应。如果目标主机不存在或无法响应,探测数据包将超时或返回错误。接......
  • 夜神模拟器如何配置BurpSuite抓包及安装Xposed框架
    希望和各位大佬一起学习,如果文章内容有错请多多指正,谢谢!  个人博客链接:CH4SER的个人BLOG–WelcomeToCh4ser'sBlog0x00 前言夜神模拟器安卓7以上直接安装证书是无法成功抓取App 的HTTPS数据包的,因为安卓7默认不再信任用户安装的证书,此时就需要使用adb将......
  • mac ---Charles抓包---ios苹果手机
    安装Charles1.获取PC的IP地址在Charles菜单栏->Help->LocalIPAddress中可以查看PC的IP地址。2.配置iPhone代理在iPhone的设置->无线局域网->局域网信息(i)->配置代理->手动中配置代理,服务器输入框中填写PC的IP地址,端口输入框中填写Charles的代理端口(一般是8888)......
  • 远程抓包的几种方式
    远程抓包远程抓包环境Linux环境SSH抓包网络转发TCP监听转发TCP直接转发Windows环境网络设备环境远端系统为linux,一般使用tcpdump;远端系统为windows,一般使用tshark(wireshark的命令行版本,包含在wireshark安装包中);近端(分析端)为linux或者windows一般使用wire......
  • fiddler 拦截抓包 安卓10
    https://blog.csdn.net/freeking101/article/details/118914275https://blog.51cto.com/u_13690151/5603754opensslx509-informder-subject_hash_old-inFiddlerRoot.cer -nooutopensslx509-informder-inFiddlerRoot.cer-oute5c3944b.0 mt管理器移到/system/e......
  • aardio教程三) 元表、元方法
    前言还有个迭代器,基础语法基本已经说完了,后面想到啥再补充,之后的教程会从以下方面来讲:基础库的使用,比如string、table等基础控件的使用,比如listview、tab等aardio和Python交互,比如给Python写个界面自带的范例程序我写的一些小程序当然,我的理解也是很基础的,特别是在界面设......
  • Golang案例开发之gopacket监听网卡抓包(2)
    文章目录前言二、实践监听网卡抓包1.代码2.知识点OpenLive方法SetBPFFilter断言总结前言本节实战,监听指定网卡,进行网络抓包,根据分层,解析不同分层包的内容。二、实践监听网卡抓包1.代码代码如下(示例):packagemainimport( "fmt" "log" "......
  • 抓包程序系统代码+过滤规则
    抓包程序的过滤规则是一种强大的功能,它允许用户根据特定的条件来筛选和显示捕获的网络数据包。在Wireshark等抓包工具中,过滤规则通常使用一种称为“显示过滤器”(Display Filter)的语法来实现。这些过滤器可以帮助用户快速定位到感兴趣的数据包,从而更有效地进行分析。以下是......
  • Linux网络抓包工具Tcpdump的3分钟快速入门手册
     Tcpdump概述tcpdump是一款强大的网络抓包工具,运行在Linux平台上。它可以帮助你分析、调试网络数据。要很好地掌握tcpdump,需要对网络报文(TCP/IP协议)有一定的了解。但对于简单的使用来说,只要有网络基础概念就足够了。此外,Tcpdump允许用户拦截和显示发送或收到过网络连接......
  • aardio教程二) 进阶语法
    表(table)aardio中除了基础数据类型外,其他的复合对象都是table(例如类和名字空间等)。table可以用来存放aardio的任何对象,包括另一个table。在其他语言中的字典、列表、数组、集合映射等,在aardio中都使用table来实现。创建字典importconsole;vartab={a=123;......