Nginx+Lua实现访问日志收集系统
网站数据统计分析工具是网站站长和运营人员经常使用的一种工具,比较常用的有谷歌分析、百度统计和腾讯分析等等。所有这些统计分析工具的第一步都是网站访问数据的收集。目前主流的数据收集方式基本都是基于javascript的。名称途径备注访问时间web serverNginx $msecIPweb serverNginx $remote_addr域名javascriptdocument.domainURLjavascriptdocument.URL页面标题javascriptdocument.title分辨率javascriptwindow.screen.height & width颜色深度javascriptwindow.screen.colorDepthReferrerjavascriptdocument.referrer浏览客户端web serverNginx $http_user_agent客户端语言javascriptnavigator.language访客标识cookie网站标识javascript自定义对象# 埋点代码12345678910<script type=& ...
使用LUA脚本绕过Applocker的测试分析
0x00 前言
在之前的文章《Bypass Windows AppLocker》曾对绕过Applocker的方法进行过学习,而最近看到一篇文章介绍了使用LUA脚本绕过Applocker的方法,学习之后产生了以下疑问:绕过原理是什么呢?能绕过哪种AppLocker的规则呢?适用条件又是什么呢?
文章地址:
https://homjxi0e.wordpress.com/2018/03/02/whitelisting-bypassing-using-lua-lanuage-wlua-com/
0x01 简介
本文将要介绍以下内容:
LUA脚本简介
绕过测试
绕过原理
适用条件
防御方法
0x02 LUA脚本简介
轻量小巧的脚本语言
用标准C语言编写
可以被C/C++ 代码调用
可以调用C/C++的函数
在目前所有脚本引擎中的速度最快
0x03 Windows系统下执行LUA脚本
1、安装Lua for Windows,下载地址:
http://files.luaforge.net/releases/luaforwindows/luaforwindows
2、输出hello worl ...
lua协程
协程是个很好的东西,它能做的事情与线程相似,区别在于:协程是使用者可控的,有API给使用者来暂停和继续执行,而线程由操作系统内核控制;另外,协程也更加轻量级。这样,在遇到某些可能阻塞的操作时,可以使用暂停协程让出CPU;而当条件满足时,可以继续执行这个协程。目前在网络服务器领域,使用Lua协程最好的范例就是ngx_lua了
来看看Lua协程内部是如何实现的。
本质上,每个Lua协程其实也是对应一个LuaState指针,所以其实它内部也是一个完整的Lua虚拟机—有完整的Lua堆栈结构,函数调用栈等等等等,绝大部分之前对Lua虚拟机的分析都可以直接套用到Lua协程中。于是,由Lua虚拟机管理着这些隶属于它的协程,当需要暂停当前运行协程的时候,就保存它的运行环境,切换到别的协程继续执行。很简单的实现。
来看看相关的API。
lua_newthread
创建一个Lua协程,最终会调用的API是luaE_newthread,Lua协程在Lua中也是一个独立的Lua类型数据,它的类型是LUA_TTHREAD,创建完毕之后会照例初始化Lua的栈等结构,有一点需要注意的是,调用preinit_st ...
Lua源码阅读:虚拟机概述
Lua 虚拟机的执行过程。
Lua 执行过程概述:解释型脚本语言与编译型语言的区别如下:
由于每个脚本语言都有自己的一套字节码,与具体的硬件平台无关,所以不用修改脚本代码,就能运行在各个平台上。硬件、软件平台的差异都由语言自身的虚拟机解决。
由于脚本语言的字节码需要虚拟机执行,而不像机器代码能够直接执行,所以运行速度比编译型语言差不少。
虚拟机需要完成以下工作:
将源代码编译成虚拟机可以识别执行的字节码。
为函数调用准备调用栈。
内部维持一个 IP(Instruction Pointer,指令指针)来保存下一个将执行的指令地址。在 Lua 代码中,IP 对应的是 PC 指针。
模拟一个 CPU 的运行:循环拿出由 IP 指向的字节码,根据字节码格式进行解码,然后执行字节码。
虚拟机的实现方式:虚拟机有两种不同的实现方式:基于栈的虚拟机和基于寄存器的虚拟机。Lua 是基于寄存器虚拟机的语言。
区别:
在基于栈的虚拟机中,字节码的操作数是从栈顶上弹出(pop),在执行完操作后再压入栈顶的,这样的缺点是会多出几条指令来准备数据,优点是指令中不需要关心操作数的地址,在执行操作之前就已 ...
Lua 学习 chapter24
目录
协程
人人真真的生活过,学习过,改变过,努力过,才能创造出一个满意的自己。
协程
协程是一系列的可执行语句,拥有自己的栈、局部变量和指令指针,同时协程又与其他协程共享了全局变量和其他几乎一切资源。线程和协程的主要区别在于,一个线程程序可以并行运行多个线程,而协程却需要彼此协作的运行,即任意指定时刻只能有一个协程运行。
协程相关的函数都在coroutine表中,其中create为创建协程函数,参数为协程要执行的代码函数。它会返回一个thread类型的协程。
一个协程拥有四种状态:挂起,运行,正常和死亡。
当一个协程被创建的时候,它处于挂起状态。函数resume用于启动或再次启动一个协程的运行,并将其状态由挂起改为运行。协程函数执行完毕之后进入死亡状态。当使用协程A唤醒协程B的时候,协程A即不是挂起状态(因为不能唤醒协程A),也不是运行状态(因为B正在运行)。所以A此时的状态就被称为正常状态。
lua语言一个非常有用的机制是通过一对resume-yield来交换数据,第一个resume函数(没有对应等待它的yield)会把所有额外参数传递给协程的主函数。
在函 ...
Lua源码阅读:标准库
Lua标准库中定义的一些函数及其实现方式。
lmathlib.c从一个简单的math.Abs()函数开始:
12345678910static int (lua_State *L) { if (lua_isinteger(L, 1)) { lua_Integer n = lua_tointeger(L, 1); if (n < 0) n = (lua_Integer)(0u - n); lua_pushinteger(L, n); } else lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1))); return 1;}
首先,先检查传入的值是否是int类型,这里调用了lapi.c中的lua_isinteger函数,检查传入值的TValue原始类型标签是否是LUA_TNUMINT,这部分的检查在lObject.h中定义的函数完成,同时数据类型LUA_TNUMINT也在lObject.h中定义:
12345#define LUA_TNUMINT (LUA_TNUMBER | (1 < ...
lua
一 概述 lua-upstream 模块提供了对 upstrem 配置的查看,查看所有的 upstream、upstream 内所有的/启用的/备用的 server,当前使用的 upstream 名。虽然有 set_peer_down 指令,但是模块只修改单个 worker 内的 server 标记(处理 set_peer_down 请求的 worker),无法再生产环境使用。 二 示例worker_processes 1;
error_log logs/error.log info;
events {
worker_connections 1024;
}
http {
lua_code_cache off;
upstream backend {
server localhost:8081 down;
server localhost:8082;
}
server {
listen 8081;
location / {
default_type text/plai ...
Lua函数重载
想法和思路在最近学习lua面向对象的时候,在想可不可以为一个类实现多个构造函数或者是new,也就是传统意义上的函数重载。尽管没有什么没有什么实际用途,毕竟想要实现同名函数的不同入参,只要入参的表内容不同即可。于是,这个问题就变成了有没有什么办法可以在Lua中从形式上实现和静态语言(比如C++)类似的函数重载。一开始思考的时候,根据lua面向对象的方式,会考虑使用元表。即:如果根据条件判断出_当前的ctor函数或者new函数的入参形式和传参不同,就向metatable中的__index检索。然后我就有些犹豫,虽然很难会出现有10个以上的ctor或者new函数的情况,但如果出现了,那不是就会变成__index检索到__index这样不停迭代的情况吗,难道真的要这样实现?也许是我思考的方向不对。于是我就换了一种思路,比如:是都存在一个表中,当要调用的时候遍历该表,用以查找同入参的函数。为了尽可能地减少搜索时间,表可以使用入参从多到少或从少到多排序,同数量的入参再根据类型排序。但这样的实现方式,依旧存在问题:如果number类型在同参数数量根据类型继续排序时,根据类型(假如类型的先后是根据类型 ...
Visual Studio 2015 Lua 环境建置
<p>Visual Studio 2015 Lua 环境建置
<br />
2016/05/10 修正内文<br />
第13步骤 由 “选择数据夹” 改为 “类库名称”
新增红色重点并附上范例项目文件(VS 2016 Project)
环境:Visual Studio 2015 UPDATE 1 & Lua 5.3.2 (.Net 4.6.1)
1.下载Lua:Source
2.解压缩该压缩档:D:lua-5.3.2
3.开启Visual Studio 2015→新增项目→Visual C++→Win32→Win32 主控台应用程序→Lua5.3→确定→下一步→静态程序库→取消勾选"先行编译标头档"→完成
4.方案总管→标头档→加入→现有项目→D:lua-5.3.2src→选取全部 *.h 文件(所有C/C++ Header文件,可先依文件类型排序后方便选择)→加入
上图右边有误:应该是要选取"新增项目"下方 ...
PIL.17Lua中的模块与包
通常,Lua并不设置什么规则,而是提供足够的方法给开发者来实现最适合他们自己的规则。然而,这些方法对于模块来说工作得并不好。模块系统的一个重要目的就是允许不同的团队共享代码。通用规则的缺乏阻碍了这个共享的实现。
从 5.1 开始,Lua就定义了一系列关于模块和包的规则(一个包就是很多模块的集合)。这些规则并不需要从语言获得额外的设置;程序员可以用我们已经见到的东西来实现它。程序员可以自由使用不同的规则。当然,有些实现可能会使程序无法使用外部的模块,或者外部的程序不能使用它。
从用户的角度看,模块就是 能通过 require加载,然后创建并返回一个表 的代码(用C或者Lua写的)。模块导出的所有东西,比如函数和常量,都定义在表内,这个表工作类似一个命名空间。
来看个例子,所有的标准库都是模块。我们可以像下面这样使用数学库:
local m = require "math"print(m.sin(3.14))
然而,发行版内的解释器预加载了所有的标准库,代码与下相等:
math = require "math"string = require "s ...