普通视图

发现新文章,点击刷新页面。
昨天以前首页

姐姐,你也不想让别人知道你的秘密吧? — 浅谈 Python 代码加密

作者 obaby
2024年8月23日 11:13

像 python 这种非编译型的语言,在代码加密上有这先天性的弱势,虽然java 之类的编译成 jar 依然比较容易反编译回来,但是毕竟也算是提升了那么一点点门槛,再加上混淆神马的,基本就能避免一些入门级的破解了。

但是对于 python 这种,如果发布不想直接让别人看代码,最简单的办法就是打包成二进制。通常的做法就是 py2exe.

官网地址:https://www.py2exe.org

py2exe

py2exe is a Python Distutils extension which converts Python scripts into executable Windows programs, able to run without requiring a Python installation.Spice

Development is hosted on GitHub. You can find the mailing listsvn, and downloads for Python 2 there. Downloads for Python 3 are on PyPI.

py2exe was originally developed by Thomas Heller who still makes contributions. Jimmy Retzlaff, Mark Hammond, and Alberto Sottile have also made contributions. Code contributions are always welcome from the community and many people provide invaluable help on the mailing list and the Wiki.

py2exe is used by BitTorrentSpamBayes, and thousands more – py2exe averages over 5,000 downloads per month.

In an effort to limit Wiki spam, this front page is not editable. Feel free to edit other pages with content relevant to py2exe. You will need an account to edit (but not to read) and your account information will be used only for the purposes of administering this Wiki.

The old py2exe web site is still available until that information has found its way into this wiki.

之前发布的各种美女爬虫基本都是通过 py2exe 打包的,虽然体积比较大,但是整体来说效果还算不错。

但是对于 web 框架,例如 flask django 之类的该怎么打包?这个就稍显麻烦一些了。

搜索一下,也能找到一些工具,例如 https://github.com/amchii/encryptpy 这个东西底层还是通过 cython 来实现的,如果不想使用这个工具,那么直接使用 cython 也是可以的,至于原理,本质上是直接把 py代码编译成了二进制文件。

下面直接用 cython 来实现:

pip install cython

编写编译脚本,叫什么无所谓,这里我的名称是cython_build.py:

from distutils.core import setup
from Cython.Build import cythonize

setup(
    ext_modules=cythonize(["application/settings.py",
                           "PowerManagement/models.py",
                           "PowerManagement/views/meter.py",
                           "PowerManagement/views/meter_remote.py",
                           "PowerManagement/views/substation_picture.py",
                           "PowerManagement/views/circuit.py",
                           ])
)

建议将上面的代码放在项目的根目录下,要处理的 modules 使用相对路径来实现。

通过下面的命令编译 py 文件:

python3 cython_build.py build_ext --inplace

但是上面的代码有个问题,那就是–inplace 并没有吧所有的 so文件放到原来的目录下,编译之后,一些文件放到了项目根目录下:

扩展名为 so 的文件就是编译生成的二进制文件,此时如果直接运行项目会提示各种组件找不到,还需要将处理后的文件复制到原来的目录下:

mv *.so PowerManagement/views/

最后一步就是删除原来的 py 文件:

cd "PowerManagement/views/"
rm  *.py

到这里整个编译流程就算完成了,可以尝试重新启动服务了。

毕竟姐姐,你也不想你的代码被人随便给抄走吧?

  •  

Delphi7 idhttpserver Post Json

作者 obaby
2024年8月6日 16:50

万万没想到,多年以后还会重新写 delphi 7 的代码。当然,代码不是全部都是自己写的,在原有的 demo 的基础上增加了一些功能。

其中,有一个需求就是需要能够远程接收 http post 的请求,请求方式是 post,数据格式是 json。然而,多年不写代码,在网上随便一搜,搜到的代码感觉都是同一个地方抄来抄去实现的,在处理 poststream 的时候都会出问题。

直到翻到了下面的代码,https://www.cnblogs.com/yangxuming/p/12462459.html

1 procedure TForm1.IdHTTPServer1CommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
 2 var
 3   tmp: UTF8String; //也可以是 array of AnsiChar; 不能用RawByteString或 widestring
 4   tmpstr: string;
 5   size: Integer;
 6   JSONObject: TJSONObject; // JSON类
 7   i: Integer;
 8   jo: ISuperObject;
 9 begin
10   size := ARequestInfo.PostStream.size;
11   SetLength(tmp, size);
12   ARequestInfo.PostStream.Position := 0;
13   ARequestInfo.PostStream.ReadBuffer(tmp[1], size); //tmp为array of AnsiChar时为tmp[0]
14   tmpstr := UTF8ToString(tmp);
15 
16   jo := SO(tmpstr);
17   Memo1.Lines.Add(jo['test'].AsString);
18 20   kbmMemTable1.Append;
21   kbmMemTable1.FieldByName('test').AsString := jo['test'].AsString;
22   kbmMemTable1.Post;
23 
24 //  Memo1.Lines.Add(ExtractFilePath(Application.ExeName) + 'testPrint.fr3');
25 
26   frxReport1.LoadFromFile(ExtractFilePath(Application.ExeName) + 'testPrint.fr3');
27   frxReport1.PrintOptions.ShowDialog := false;
28   frxReport1.ShowProgress := False;
29   frxReport1.PrepareReport;
30   frxReport1.Print;
31 
32 //  JSONObject := TJSONObject.ParseJSONValue(Trim(tmpstr)) as TJSONObject;
33 //  for i := 0 to JSONObject.Count - 1 do
34 //    Memo1.Lines.Add(JSONObject.Pairs[i].JsonString.ToString + '=' +
35 //      JSONObject.Pairs[i].JsonValue.ToString);
36 end;

这里的处理逻辑是争取的,poststream 貌似不能直接将 stream 转换为 stringstream 或者 memorystream,在后续的转换过程中会出错,当然,也可能是由于 stream 的Position位置异常导致的。

另外 一个问题就是处理 json,网上的代码多数都是一笔带过,但是这个一笔带过就很烦人,找个可用的 json 库也比较麻烦,TJSONObject这个东西,看很多代码说都是内置的,但是实际在使用的时候,会提示找不到这个类。

所以,可以借助第三方的 json 库,例如https://github.com/frostney/superobject

通过这个东西来解析 json 就简单多了:

var
  obj: ISuperObject;
begin
  obj := SO('{"foo": true}');
  obj := TSuperObject.ParseString('{"foo": true}');
  obj := TSuperObject.ParseStream(stream);
  obj := TSuperObject.ParseFile(FileName);
end;
val := obj.AsObject.S['foo']; // get a string
 val := obj.AsObject.I['foo']; // get an Int64
 val := obj.AsObject.B['foo']; // get a Boolean
 val := obj.AsObject.D['foo']; // get a Double
 val := obj.AsObject.O['foo']; // get an Object (default)
 val := obj.AsObject.M['foo']; // get a Method
 val := obj.AsObject.N['foo']; // get a null object

现在 ai 生成的代码质量的确也是个问题,这些小众(当前)语言生成的效果就更差了。

  •  

Gunicorn nginx 反代获取真实 ip 地址

作者 obaby
2024年7月17日 15:21

闺蜜圈的后台服务使用 gunicorn 运行,对外接口通过 nginx 进行反代。但是反代有个问题,那就是 gunicorn 获取到的服务器的 ip 地址都是 127.0.0.1。

作为一个强迫症能忍受这个?那自然不行啊。

在 nginx 配置文件中增加 proxy_set_header

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

修改 gunicorn 启动参数,修改日志格式为:

--access-logformat='%({X-Real-IP}i)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"'

重启 nginx 以及 gunicorn 服务,就可以记录真实 ip 地址了:

参数说明:

h is the remote address
l is - (not used)
u is - (not used, reserved)
t is the time stamp
r is the status line
s is the status of the request
b is length of response
f is referrer
a is user agent
You can also customize it with the following extra variables that are not used by default:

T - request time (in seconds)
D - request time (in microseconds)
p - the process id
{Header}i - request header (custom)
{Response}o - response header (custom)

 

参考链接:https://stackoverflow.com/questions/25737589/gunicorn-doesnt-log-real-ip-from-nginx

  •  
❌
❌