教程 | vscode ssh远程linux开发c/c++界面程序


背景

最近又要处理统信的适配,现在的场景就是把代码放到实体机上进行编译,每次都得来回跑。。。
最近捣鼓了一下新方式进行处理,使用vscode作为代码编辑通过ssh链接linux机器,然后运行软件用x11的形式回显,这样就能在自己的机器上完美的远程编译与测试。x server在windows上的显示建议用VcXsrv,因为Xming这个东西对GLX支持的不怎么好,运行glxgears会黑屏。

环境

  1. 一台被远程的Linux机器,并且开启ssh服务
  2. 编辑器软件:vscode
  3. XServer服务: VcXsrv 或者是 Xming(还需要安装Xming-fronts才能运行)

本地vcxsrv-64.1.20.14.0.installer.zip

安装步骤

ssh免密登录

在windows中按下win+R快捷键进入cmd命令框中运行命令ssh-keygen
会在C:\Users\Administrator\.ssh文件夹下生成了两个文件

id_rsa.pub # 公钥
id_rsa # 私钥

登录服务器,在用户的.ssh目录下生成authorized_keys,该文件包含一系列允许登录该服务器的公钥,没有就新建该文件。将公钥内容追加到~/.ssh/authorized_keys

echo "公钥内容" >> ~/.ssh/authorized_keys

并在配置文件C:\Users\Administrator\.ssh\config中的对应主机下添加如下内容:

IdentityFile "C:\Users\Administrator\.ssh\id_rsa"//设置私钥路径

vscode 安装插件

本地安装【Remote - SSH】插件。
ssh连接服务器安装【Remote X11】和【Remote X11 (ssh)】两个插件。

配置

并在配置文件C:\Users\Administrator\.ssh\config中的对应主机下添加如下内容:

ForwardX11 yes
ForwardX11Trusted yes
ForwardAgent yes

本地安装X11服务

下载完VcXsrv直接安装就行,一路下一步。
安装完之后点击XLaunch.exe启动,会弹出一个配置界面。
选中Multiple windows后填写视窗ID,这里填的是0(根据自己的情况而定)下一步
CIOMP_2024-06-18_16-19-59.png
选择程序启动方式,默认就行,下一步。
CIOMP_2024-06-18_16-55-45.png
这里将禁用访问控制的配置项勾上,然后下一步,再就是完成,会在右下角留下X的图标,等待客户端的连接。
CIOMP_2024-06-18_16-58-25.png

putty的X11显示程序

配置在Connection->SSH->X11里,这里勾选Enable X11 forwaring,X display Location这个填localhost:11.0,默认转发到本地是localhost:0.0(啥也不填的情况)(会自动设置服务器的DISPLAY值),如果想修改其他端口也可以。
CIOMP_2024-06-20_20-16-10.png
配置好后连接远程linux服务器。

注:这里需要注意一下,linux的端口是putty自动设置的,会将linux设置的端口转发成本地设置端口,所以XServer的端口应与putty内设置的端口一致。

测试一下:

ciomp@ciomp-PC:~$ echo $DISPLAY
localhost:10.0
ciomp@ciomp-PC:~$ xclock
Warning: Missing charsets in String to FontSet conversion

显示效果如下:
CIOMP_2024-06-20_20-07-00.png

vscode的X11显示程序

remote x11插件配置display端口为11(根据本地XServer开启的端口一致),其他默认即可,如下:
CIOMP_2024-06-20_20-26-54.png

打开一个测试程序,配置好launch.json文件直接F5运行,效果如下
CIOMP_2024-06-20_20-31-43.png

直接在vscode终端执行测试如下:
CIOMP_2024-06-22_09-26-04.png

直接在vscode终端执行测试2如下:
CIOMP_2024-09-15_17-12-12.png

如果配置正确,但是连接出现错误的话(比如连了一宿)可以ctrl+shift+p调出命令输入框执行Remote X11: Reconnect Display

VSCode Server 下载时间过长问题

正常通过ssh连接的时候vscode会让远程机器下载VSCode Server,如果未联网或者下载慢请按如下操作:

打开VScode的帮助-关于(help-about)模块,出现Version,Commit,Data,Electron等信息,其中最关键的是Commit后面的字符串,被称为Commit ID,其是由40位十六进制字符串,利用Commit ID下载VScode Server,文件为vscode-server-linux-x64.tar.gz,下载链接有两个

https://update.code.visualstudio.com/commit:${commit_id}/server-linux-x64/stable

https://vscode.download.prss.microsoft.com/dbazure/download/stable/${commit_id}/vscode-server-linux-x64.tar.gz 

注意把:${commit_id}替换成对应的Commit ID

下载后将vscode-server-linux解压到连接用户的目录下的.vscode-server/bin/${commit_id}下,具体操作如下:

# 1 在/home/usr/下新建文件夹.vscode-server/bin/${commit_id}
mkdir -p ~/.vscode-server/bin/${commit_id}
# 2 将vscode-server-linux-x64.tar.gz文件放置在${commit_id}目录下,并进入该文件夹
cd ~/.vscode-server/bin/${commit_id}
# 3 解压文件vscode-server-linux-x64.tar.gz
tar -xvzf vscode-server-linux-x64.tar.gz --strip-components 1
# 4 删除多余文件vscode-server-linux-x64.tar.gz
rm vscode-server-linux-x64.tar.gz
# 5 重启VScode,在安装完成Remote-ssh后,可通过ssh连接远程服务器,此时会生成data,extensions文件夹,可以连接成功,表明VScode-Server安装成功。

教程 | PowerDNS的部署与使用


PowerDNS简介

PowerDNS是一个跨平台的开源DNS服务组件,成立于20世纪90年代末,是开源DNS软件、服务和支持的主要供应商。它提供了三个核心组件:Authoritative、Recursor和dnsdist,分别作为权威服务器、域名递归解析和DNS服务负载均衡来使用,每个服务独立存在,可根据需求进行部署。PowerDNS支持多种数据库后端,包括MySQL、PostgreSQL和SQLite等,以适应不同的实际需求。在Windows环境下,PowerDNS使用Access的mdb文件记录DNS信息,而在Linux/Unix环境下则使用MySQL来记录。

PowerDNS的主要特点包括高性能、可扩展性、安全性和灵活性。它采用多线程和多进程的架构,能够处理大量的DNS查询请求,并提供快速的响应时间。同时,PowerDNS支持分布式部署,可以通过添加更多的服务器来扩展系统的容量和吞吐量。在安全性方面,PowerDNS具有DNSSEC(DNS安全扩展)支持和防止DNS缓存污染等功能。

安装

# 这边是用ubuntu。
sudo apt install pdns pdns-backend-mysql pdns-recursor

配置

mysql

mysql的服务上网找,我这里用的宝塔。
创建pdns_server数据库

CREATE TABLE domains (
  id                    INT AUTO_INCREMENT,
  name                  VARCHAR(255) NOT NULL,
  master                VARCHAR(128) DEFAULT NULL,
  last_check            INT DEFAULT NULL,
  type                  VARCHAR(6) NOT NULL,
  notified_serial       INT DEFAULT NULL,
  account               VARCHAR(40) DEFAULT NULL,
  PRIMARY KEY (id)
) Engine=InnoDB;
 
CREATE UNIQUE INDEX name_index ON domains(name);
 
CREATE TABLE records (
  id                    BIGINT AUTO_INCREMENT,
  domain_id             INT DEFAULT NULL,
  name                  VARCHAR(255) DEFAULT NULL,
  type                  VARCHAR(10) DEFAULT NULL,
  content               BLOB(64000) DEFAULT NULL,
  ttl                   INT DEFAULT NULL,
  prio                  INT DEFAULT NULL,
  change_date           INT DEFAULT NULL,
  disabled              TINYINT(1) DEFAULT 0,
  ordername            VARCHAR(255) BINARY DEFAULT NULL,
  auth                  TINYINT(1) DEFAULT 1,
  PRIMARY KEY (id)
) Engine=InnoDB;
 
CREATE INDEX nametype_index ON records(name,type);
CREATE INDEX domain_id ON records(domain_id);
CREATE INDEX recordorder ON records (domain_id, ordername);
 
CREATE TABLE supermasters (
  ip                    VARCHAR(64) NOT NULL,
  nameserver            VARCHAR(255) NOT NULL,
  account               VARCHAR(40) NOT NULL,
  PRIMARY KEY (ip, nameserver)
) Engine=InnoDB;
 
CREATE TABLE comments (
  id                    INT AUTO_INCREMENT,
  domain_id             INT NOT NULL,
  name                  VARCHAR(255) NOT NULL,
  type                  VARCHAR(10) NOT NULL,
  modified_at           INT NOT NULL,
  account               VARCHAR(40) NOT NULL,
  comment               BLOB(64000) NOT NULL,
  PRIMARY KEY (id)
) Engine=InnoDB;
 
CREATE INDEX comments_domain_id_idx ON comments (domain_id);
CREATE INDEX comments_name_type_idx ON comments (name, type);
CREATE INDEX comments_order_idx ON comments (domain_id, modified_at);
 
CREATE TABLE domainmetadata (
  id                    INT AUTO_INCREMENT,
  domain_id             INT NOT NULL,
  kind                  VARCHAR(32),
  content               TEXT,
  PRIMARY KEY (id)
) Engine=InnoDB;
 
CREATE INDEX domainmetadata_idx ON domainmetadata (domain_id, kind);
 
CREATE TABLE cryptokeys (
  id                    INT AUTO_INCREMENT,
  domain_id             INT NOT NULL,
  flags                 INT NOT NULL,
  active                BOOL,
  content               TEXT,
  PRIMARY KEY(id)
) Engine=InnoDB;
 
CREATE INDEX domainidindex ON cryptokeys(domain_id);
 
CREATE TABLE tsigkeys (
  id                    INT AUTO_INCREMENT,
  name                  VARCHAR(255),
  algorithm             VARCHAR(50),
  secret                VARCHAR(255),
  PRIMARY KEY (id)
) Engine=InnoDB;
 
CREATE UNIQUE INDEX namealgoindex ON tsigkeys(name, algorithm);

pdns server

vim /etc/pdns/pdns.conf
#设置数据库相关的
launch=gmysql
gmysql-host=10.0.0.110
gmysql-port=3306
gmysql-dbname=pdns_server
#管理数据库的相关用户和密码
gmysql-user=pdns_server
gmysql-password=pdns_server
#访问权限
allow-axfr-ips=0.0.0.0/0,::1
allow-dnsupdate-from=0.0.0.0/0,::1
allow-notify-from=0.0.0.0/0,::/0
allow-unsigned-notify=yes
also-notify=10.0.0.10
#daemon 启动
daemon=yes
disable-axfr=no
guardian=no
#是否master
master=yes
#是否slave
slave=no
#启动权限
setgid=pdns
setuid=pdns
#打印日志
log-dns-details=yes
log-dns-queries=no
loglevel=6
log-timestamp=yes
logging-facility=0
#开启api
api=yes
api-key=dnsadmin1syn
#启动webserver 监控
webserver=yes
webserver-address=0.0.0.0
webserver-allow-from=0.0.0.0/0
webserver-port=8081
#监听的地址端口
local-address=0.0.0.0
local-port=54
#记录query 日志
query-logging=yes

pdns-recursor 递归解析

vim /etc/pdns-recursor/recursor.conf
#允许访问的地址
allow-from=0.0.0.0/0
#开启日志
disable-syslog=yes
#关闭dnssec 转发有用
dnssec=off
#forward-zones是只转发,不递归 少用
#forward-zones=hexug.com=127.0.0.1:54
#forward-zones-recurse是找不到就递归,找的到就转发,用逗号分隔  这里是将pdns中定义的域名,转发到pdns服务的54端口上
forward-zones-recurse=test.com=127.0.0.1:54,abc.com=127.0.0.1:54,.=114.114.114.114
#绑定在所有端口商
local-address=0.0.0.0
local-port=53
log-common-errors=yes
security-poll-suffix=
setgid=pdns-recursor
setuid=pdns-recursor

启动服务并且设置为开机启动

sudo systemctl start pdns
sudo systemctl start pdns-recursor
sudo systemctl enable pdns
sudo systemctl enable pdns-recursor

WEB管理界面 phpDNSadmin

源码Github地址
PowerDNS-Admin-0.4.2.zip 下载地址

部署的话直接用的宝塔python项目部署的。就不介绍了。


工具 | office文档密码找回(附下载)!


Advanced Office Password Recovery(AOPR)

AOPR是一能解除Office文档密码的一款软件,下边说一下他的安装和使用教程。

安装

  1. 下载软件

Advanced.Office.Password.Recovery.Pro.6.01.632.rar

  1. 解压并安装
    直接执行aopr_setup_en.msi安装
  2. 安装途中输入下面激活码

激活码:AOPRS-V400-TJWTY-25328-WTPCC-79837

  1. 下一步安装完成

使用

  1. 点击Open File选择你要解除密码的文件

CIOMP_2024-03-15_14-34-50.png

  1. 直接默认bruteforce attack(野兽攻击) 其实就是所有模式都尝试
  2. 等待出结果
    CIOMP_2024-03-15_14-34-01.png

C++ | Linux下源码编译VTK6.1


背景

occ需要vtk依赖。

过程

  1. 添加cmake配置,c++标注指定11的版本

CMAKE_CXX_STANDARD 11

  1. 修改CMake文件,让其使用更高版本的gcc
    这边gcc版本为11.4的,所以3或4开头的需要修改11开头

CMake/GenerateExportHeader.cmake内的169行
CMake/vtkCompilerExtras.cmake内的30行
[34]修改成[0-9]+

  1. 修复error: ‘GLintptr’ has not been declared等报错
    /usr/include/GL/glxext.h文件先备份一下

sudo cp /usr/include/GL/glxext.h /usr/include/GL/glxext.h.bak

在此文件的474行添加下边两句话

typedef ptrdiff_t GLsizeiptr;
typedef ptrdiff_t GLintptr;
  1. 编译及安装make -j8 && make install

C++ | window下生成dump文件的死机报告解决程序异常崩溃


代码部分

依赖库 DbgHelp

win下直接链接引入即可: target_link_libraries(${PROJECT_NAME} DbgHelp)

头文件引入

#include <DbgHelp.h>

win异常处理函数注册

#ifdef WIN32
    // 注册异常处理函数
    LPTOP_LEVEL_EXCEPTION_FILTER Top = SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)ApplicationCrashHandler);
    // 此函数与搜狗输入法冲突,会导致编译不过或程序运行崩溃
    // DisableSetUnhandledExceptionFilter();
#endif

异常处理执行函数代码如下

#ifdef WIN32
// 崩溃相关处理函数
LONG WINAPI ApplicationCrashHandler(EXCEPTION_POINTERS *pException){


    //这里弹出一个错误对话框并退出程序
    EXCEPTION_RECORD* record = pException->ExceptionRecord;


    QString errCode(QString::number((uint)record->ExceptionCode,16)),
            errAdr(QString::number(PtrToInt(record->ExceptionAddress),16)), 
            errMod;


    // 崩溃日志写入
    LOG_ERROR(QString::fromLocal8Bit("错误代码:%1 错误地址:%2").arg(errCode).arg(errAdr).toStdString().c_str());


    // 创建错误文件
    HANDLE dumpFile = CreateFile((LPCWSTR)QString("./error.dmp").utf16(),GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if(dumpFile != INVALID_HANDLE_VALUE)
    {
        MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
        dumpInfo.ExceptionPointers = pException;
        dumpInfo.ThreadId = GetCurrentThreadId();
        dumpInfo.ClientPointers = TRUE;


        MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), dumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL);
        CloseHandle(dumpFile);
        LOG_INFO(QString::fromLocal8Bit("调试信息生成成功。").toStdString().c_str());
    }else{
        LOG_ERROR(QString::fromLocal8Bit("调试信息文件生成失败。").toStdString().c_str());
    }


    QMessageBox::critical(NULL,
                          QString::fromLocal8Bit("程式崩溃"),
                          QString::fromLocal8Bit("<FONT size=4><div><b>对于发生的错误,表示诚挚的歉意</b><br/></div>")+
                          QString::fromLocal8Bit("<div>错误代码:%1</div><div>错误地址:%2</div></FONT>").arg(errCode).arg(errAdr),
                          QMessageBox::Ok);


    //EXCEPTION_EXECUTE_HANDLER
    return EXCEPTION_EXECUTE_HANDLER;
    // return EXCEPTION_CONTINUE_EXECUTION;
}


//防止CRT(C runtime)函数报错可能捕捉不到,这里与搜狗输入法存在bug,回到这程序起不来(暂时不执行此函数)
void DisableSetUnhandledExceptionFilter()
{
    void* addr = (void*)GetProcAddress(LoadLibrary(L"kernel32.dll"), "SetUnhandledExceptionFilter");
    if(addr)
    {
        unsigned char code[16];
        int size = 0;


        code[size++] = 0x33;
        code[size++] = 0xC0;
        code[size++] = 0xC2;
        code[size++] = 0x04;
        code[size++] = 0x00;


        DWORD dwOldFlag, dwTempFlag;
        VirtualProtect(addr, size, PAGE_READWRITE, &dwOldFlag);
        WriteProcessMemory(GetCurrentProcess(), addr, code, size, NULL);
        VirtualProtect(addr, size, dwOldFlag, &dwTempFlag);
    }
}
#endif

文件处理过程

在程序崩溃后会在指定目录下生成dmp文件(代码内指定了./error.dmp),正常在根目录找到error.dmp文件拖拽到visual studio中,右侧红框内可选择对应pdb进行调试。
65af2c1c92e38.png