本文目的在于向读者说明程序进行自我修改的基本方法,并希望可以起到抛砖引玉的作用。
如果读者有更好的方法或见解,欢迎来信交流E-mail: default_and_default@yahoo.cn
/*//////////////////////////////////////////////////////////////////////////////
This program will modify itself at the running time,
These methods will be very useful in some situations,
Gook Luck!
//////////////////////////////////////////////////////////////////////////////*/
#include<stdio.h>
#include<windows.h>
void main()
{
TCHAR Info001[MAX_PATH]="Welcome to Big Apple!";
TCHAR Info002[MAX_PATH]="Welcome to Washington!";
char temp=(char)0x90;
WORD temp001=0x9090;
DWORD temp002=0x90909090;
PVOID BaseAddressOne=NULL;
PVOID BaseAddressTwo=NULL;
_asm
{
mov BaseAddressOne,offset LabelOne
mov BaseAddressTwo,offset LabelTwo
}
MessageBox(NULL,Info001,"Information",MB_OK|MB_ICONINFORMATION);
//a kind of method to modify itself
WriteProcessMemory(GetCurrentProcess(),BaseAddressTwo,&temp001,2,NULL);
WriteProcessMemory(GetCurrentProcess(),BaseAddressOne,&temp001,2,NULL);
/*
//Another method to modify itself,this method needs to modify the code section's
//characteristics in PE file.
_asm
{
mov ebx,BaseAddressOne
mov ecx,BaseAddressTwo
mov dx,temp001
mov [ebx],dx
mov [ecx],dx
}
*/
LabelTwo:
_asm
{
jmp LabelOne
}
_asm
{
nop
nop
nop
}
MessageBox(NULL,Info002,"Information",MB_OK|MB_ICONINFORMATION);
LabelOne:
_asm
{
jmp Over
}
MessageBox(NULL,Info002,"Information",MB_OK|MB_ICONINFORMATION);
Over:
return;
}
编译这个程序,我们发现WriteProcessMemory() 成功修改了程序自身代码,程序运行正常。
然后我们屏蔽程序中的WriteProcessMemory()调用,用/* */之中的代码完成自我修改,
运行后会发现系统抛出异常 Access Violation.这是因为PE 中 代码节的属性默认为 0x60000020,
20 表示代码 20000000表示可执行,40000000表示可读,如果我们在此基础上加上 0x80000000(可写)
操作系统的loader在装载可执行文件时,便会将存放代码节数据的内存标记为可读,可写,可执行。
这样就不会有异常了。
读者可使用下面的程序来修改节属性:
/**************************************************************************************/
//The following code is used to modify characteristics of sections
#include<windows.h>
#include<stdio.h>
BOOL ModifyCharacteristicsOfSections (LPCTSTR FileName)
{
DWORD i=0;
HANDLE hDestinationFile=NULL;
TCHAR DestinationPEFile[MAX_PATH];
DWORD NumberOfBytesRead=0; //Number of bytes read
DWORD NumberOfBytesWritten=0; //Number of bytes written
DWORD ImageNtSignature=0; //PE signature
DWORD OffsetOfNewHeader=0;
DWORD NumberOfSections=0;
DWORD SizeOfSectionTable=0; //size of section table
HANDLE hGlobalAllocatedMemory=NULL; //use GlobalAlloc();
PIMAGE_SECTION_HEADER pImageSectionHeader=NULL; //a pointer to IMAGE_SECTION_TABLE
IMAGE_DOS_HEADER ImageDosHeader;
IMAGE_NT_HEADERS ImageNTHeaders;
IMAGE_FILE_HEADER ImageFileHeader;
IMAGE_OPTIONAL_HEADER ImageOptionalHeader;
IMAGE_SECTION_HEADER ImageSectionHeader;
DWORD dwFileSize=0;
RtlZeroMemory(&ImageDosHeader,sizeof(IMAGE_DOS_HEADER));
RtlZeroMemory(&ImageNTHeaders,sizeof(IMAGE_NT_HEADERS));
RtlZeroMemory(&ImageFileHeader,sizeof(IMAGE_FILE_HEADER));
RtlZeroMemory(&ImageOptionalHeader,sizeof(IMAGE_OPTIONAL_HEADER));
RtlZeroMemory(&ImageSectionHeader,sizeof(IMAGE_SECTION_HEADER));
strcpy(DestinationPEFile,FileName);
hDestinationFile=CreateFile(DestinationPEFile,
FILE_WRITE_DATA|FILE_READ_DATA,
FILE_SHARE_WRITE,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,NULL);
if(hDestinationFile==INVALID_HANDLE_VALUE)
{
// printf("/nCreateFile() fails!Can't open file. Please try again!/n");
// CloseHandle(hDestinationFile);
return TRUE;
}
else
{
dwFileSize=GetFileSize(hDestinationFile,NULL);
}
SetFilePointer(hDestinationFile,0,NULL,FILE_BEGIN); //Revert the file pointer,this is very important.
ReadFile(hDestinationFile,&ImageDosHeader,
sizeof(IMAGE_DOS_HEADER),&NumberOfBytesRead,NULL);
if(NumberOfBytesRead!=sizeof(IMAGE_DOS_HEADER))
{
// printf("/nReadFile() fails! Can't get IMAGE_DOS_HEADER./n");
CloseHandle(hDestinationFile);
return FALSE;
}
OffsetOfNewHeader=ImageDosHeader.e_lfanew; //File address of new exe header
SetFilePointer(hDestinationFile,(LONG)OffsetOfNewHeader,NULL,FILE_BEGIN);
ReadFile(hDestinationFile,&ImageNTHeaders,
sizeof(IMAGE_NT_HEADERS),&NumberOfBytesRead,NULL); //Retrieve IMAGE_NT_HEADERS
if(NumberOfBytesRead!=sizeof(IMAGE_NT_HEADERS))
{
CloseHandle(hDestinationFile);
return FALSE;
}
if(ImageNTHeaders.Signature!=0x00004550)
{
// printf("Error./nPE signature is invalid!/n");
CloseHandle(hDestinationFile);
return FALSE;
}
SetFilePointer(hDestinationFile,OffsetOfNewHeader+4,NULL,FILE_BEGIN); //Set the file pointer to point to IMAGE_FILE_HEADER
ReadFile(hDestinationFile,&ImageFileHeader,
sizeof(IMAGE_FILE_HEADER),&NumberOfBytesRead,NULL); //Retrieve IMAGE_FILE_HEADER
if(NumberOfBytesRead!=sizeof(IMAGE_FILE_HEADER))
{
// printf("/nReadFile() fails! Can't get IMAGE_FILE_HEADER./n");
CloseHandle(hDestinationFile);
return FALSE;
}
if(ImageFileHeader.NumberOfSections<1)
{
CloseHandle(hDestinationFile);
return FALSE;
}
if(dwFileSize<(sizeof(IMAGE_DOS_HEADER)+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER)*ImageFileHeader.NumberOfSections))
{
CloseHandle(hDestinationFile);
return FALSE;
}
ReadFile(hDestinationFile,&ImageOptionalHeader,
sizeof(IMAGE_OPTIONAL_HEADER),&NumberOfBytesRead,NULL); //Retrieve IMAGE_OPTIONAL_HEADER
if(NumberOfBytesRead!=sizeof(IMAGE_OPTIONAL_HEADER))
{
// printf("/nReadFile() fails! Can't get IMAGE_OPTIONAL_HEADER./n");
CloseHandle(hDestinationFile);
return FALSE;
}
if(ImageOptionalHeader.SectionAlignment<ImageOptionalHeader.FileAlignment)
{
CloseHandle(hDestinationFile);
return FALSE;
}
NumberOfSections=ImageFileHeader.NumberOfSections; //Number of sections
SizeOfSectionTable=sizeof(IMAGE_SECTION_HEADER)*NumberOfSections; //Get the size of Section Table
hGlobalAllocatedMemory=GlobalAlloc(GPTR,SizeOfSectionTable); //Allocate memory and initialize with zero
if(hGlobalAllocatedMemory==NULL)
{
// printf("/nGlobalAlloc() failed! Please try again./n"); //if failed,return
CloseHandle(hDestinationFile);
return FALSE;
}
pImageSectionHeader=(PIMAGE_SECTION_HEADER)hGlobalAllocatedMemory; //Convert a handle to a pointer to IMAGE_SECTION_HEADER
for(i=0;i<NumberOfSections;i++) //Retrieve the Section Table
{
ReadFile(hDestinationFile,pImageSectionHeader+i,
sizeof(IMAGE_SECTION_HEADER),&NumberOfBytesRead,NULL);
if(NumberOfBytesRead!=sizeof(IMAGE_SECTION_HEADER))
{
// printf("Error.Can't get IMAGE_SECTION_HEADER./n");
CloseHandle(hDestinationFile);
return FALSE;
}
}
for(i=0;i<NumberOfSections;i++)
{
DWORD dwTempCharacteristics=0;
if((*(pImageSectionHeader+i)).PointerToRawData+(*(pImageSectionHeader+i)).SizeOfRawData>dwFileSize)
{
CloseHandle(hDestinationFile);
return FALSE;
}
if((*(pImageSectionHeader+i)).PointerToRawData % ImageOptionalHeader.FileAlignment!=0)
{
CloseHandle(hDestinationFile);
return FALSE;
}
printf("/nThe name of the section%d: ",i);
printf("%s/n",(*(pImageSectionHeader+i)).Name);
printf("Characteristics: %#x/n",(*(pImageSectionHeader+i)).Characteristics);
printf("/nPlease input the new characteristics of the section./n");
printf("If you enter 0,the characteristics of the section will not be modified./n");
scanf("%x",&dwTempCharacteristics);
if(dwTempCharacteristics!=0)
(*(pImageSectionHeader+i)).Characteristics=dwTempCharacteristics;
printf("------------------------------------------------------");
}
SetFilePointer(hDestinationFile,-((long)SizeOfSectionTable),NULL,FILE_CURRENT); //Set the file poiner
WriteFile(hDestinationFile,pImageSectionHeader,SizeOfSectionTable,&NumberOfBytesWritten,NULL);
if(NumberOfBytesWritten==SizeOfSectionTable)
{
printf("/nComplete successfully!/n");
}
else
{
printf("/nWriteFile() failed!/n");
}
GlobalFree(hGlobalAllocatedMemory); //Free memory
CloseHandle(hDestinationFile);
return TRUE;
}
void main(int argc,char *argv[])
{
if(argc!=2)
{
printf("Error/nUsage:ModifyCharacteristicsOfSections CompleteDestinationFileName/n");
return;
}
if(!ModifyCharacteristicsOfSections(argv[1]))
{
printf("/nError.This usually means that this file is not a valid PE file or/n");
printf("that this PE file has been modified by another program,for example,shell programm./n");
}
}
/**********************************************************************************************/
以下是上面程序的输出信息:
The name of the section0: .text
Characteristics: 0x60000020
Please input the new characteristics of the section.
If you enter 0,the characteristics of the section will not be modified.
e0000020
------------------------------------------------------
The name of the section1: .rdata
Characteristics: 0x40000040
Please input the new characteristics of the section.
If you enter 0,the characteristics of the section will not be modified.
0
------------------------------------------------------
The name of the section2: .data
Characteristics: 0xc0000040
Please input the new characteristics of the section.
If you enter 0,the characteristics of the section will not be modified.
0
------------------------------------------------------
The name of the section3: .idata
Characteristics: 0xc0000040
Please input the new characteristics of the section.
If you enter 0,the characteristics of the section will not be modified.
0
------------------------------------------------------
The name of the section4: .reloc
Characteristics: 0x42000040
Please input the new characteristics of the section.
If you enter 0,the characteristics of the section will not be modified.
0
------------------------------------------------------
Complete successfully!
////////////////////////////////////////////////////////////////////////////
The name of the section0: .text
Characteristics: 0xe0000020
Please input the new characteristics of the section.
If you enter 0,the characteristics of the section will not be modified.
0
------------------------------------------------------
The name of the section1: .rdata
Characteristics: 0x40000040
Please input the new characteristics of the section.
If you enter 0,the characteristics of the section will not be modified.
0
------------------------------------------------------
The name of the section2: .data
Characteristics: 0xc0000040
Please input the new characteristics of the section.
If you enter 0,the characteristics of the section will not be modified.
0
------------------------------------------------------
The name of the section3: .idata
Characteristics: 0xc0000040
Please input the new characteristics of the section.
If you enter 0,the characteristics of the section will not be modified.
0
------------------------------------------------------
The name of the section4: .reloc
Characteristics: 0x42000040
Please input the new characteristics of the section.
If you enter 0,the characteristics of the section will not be modified.
0
------------------------------------------------------
Complete successfully!
相关推荐
QT+QTimer+QThread实现线程内的定时任务并且和主线程进行交互
在制作qt软件时,我们经常会用到qtimer定时器以及将其在非主线程中进行使用,甚至有的时候还需要和主线程进行交互。我总结了两种用法,仅供参考。以上即为QTimer和QThread联合使用的学习记录。
程序的自我修改
本文目的在于向读者说明程序进行自我修改的基本方法,并希望可以起到抛砖引玉的作用。如果读者有更好的方法或见解,欢迎来信交流E-mail: default_and_default@yahoo.cn/*//////////////////////////////////////////////////////////////////////////////This program will modify
文章详细介绍了进行DoIP(DiagnosticoverInternetProtocol)测试的完整过程,包括样件的正确接线、CANoe软件的环境配置、端口设置、VLAN配置、IP和MAC地址的设定
关于Tester和DUT的地址,其实最主要的就是DUT的IP、MAC和逻辑地址,如果不知道Tester的IP、MAC和逻辑地址,可以配置为与DUT同一网段的就可以。ps:最重的是知道DUT的IP、逻辑、MAC地址,如果有VLAN也需要知道,Tester的地址可以根据DUT地址进行设定,其余的值可根据DoIP的报文查到相关参数。ps:如果在通信中没有建立VLAN,但是源地址和目的地址都填写正确,此时就要考虑是否是遗漏了VLAN,建立一个VLAN,在重新试试是否可通信。此处与硬件连接是相对应的,要注意!
程序自修改(SMC)
理论:所谓SMC(Self Modifying Code)技术,就是一种将可执行文件中的代码或数据进行加密,防止别人使用逆向工程工具对程序进行静态分析的方法,只有程序运行时才对代码和数据进行解 密,从而正常运行程序和访问数据。本篇通过一个简单的实例来介绍这个技术。需要的运行环境vc6,程序编译为release版。由于本篇我们要在程序执行过程中,修改代码段中的一个函数内容,而默认情况下,我们编译生成
矩阵管理:一人100账号霸屏小红书,保姆级教程经验技巧
同时,如果你的账号表现很正常,很OK,它也增加账号权重。手机环境:一机一卡一号是基本操作,如果你觉得设备成本高,你就要知道WIN的云真机,一键新机,一键随机设备参数,一键还原,一键安装应用,自带批量发布笔记,私信聚合,自带回复私信,一键养号等等,一人批量注册100个小红书账号真的很简单!从流量逻辑来分析,大家有没有发现,从账号粉丝数来看,小红书很难出现类似抖音上超千万粉丝量级的账号,几十万粉丝的博主已经是头部账号了,原因在于,抖音的流量分发机制是80%的流量集中在 20% 的头部账号而。
从URDF到仿真动画:基于Simulink、Simscape与S-Function的机械臂一体化建模与控制
本文详细介绍了从URDF文件到高保真仿真动画的一体化机械臂建模与控制流程。通过整合Simulink、Simscape与S-Function,构建了包含物理特性的虚拟机械臂模型,并实现了自适应滑模等高级控制算法的嵌入与验证。该流程打通了从机械设计到控制算法验证的闭环,为机器人开发提供了高效的仿真平台。
自修改代码浅析
相信大家都在程序调试或者分析中碰到过自修改代码的情况吧。所谓自修改代码,就是程序自我保护的一种机制。它使我们的反汇编调试器看起来相当地无助。因为我们看到的所谓的反汇编代码并非执行过程中的代码,它表面上看起来不合逻辑甚至一塌糊涂,但是运行起来却井井有条。因此,这项技术被广泛用在那些反破解的商业软件中,在试图bypass杀毒软件的黑客软件中也颇有涉及。在另一方面,cracker
Theil-Sen Median斜率估计和Mann-Kendall趋势分析:以多年NPP数据为例
一、理论 Theil-Sen Median方法又称为Sen斜率估计,是一种稳健的非参数统计的趋势计算方法。该方法计算效率高,对于测量误差和利群数据不敏感,适用于长时间序列数据的趋势分析。其计算公式为: Mann-Kendall(MK)检验是一种非参数的时间序列趋势性检验方法,其不需要测量值服从正太分布,不受缺失值和异常值的影响,适用于长时间序列数据的趋势显著检验。其过程如下:对 于 序 列Xt = x1,x2,⋯xn,先确定所有对偶值( xi , xj ,...
【计算机系统结构】Self-modifying code 自修改代码
Self-modifying code 在计算机科学中,自修改代码是一种代码,当代码执行时修改它自身的指令,通常用于减少指令路径长度以提高性能或简单地减少额外的,重复的,相似的代码,以此来简化维护。自修改是“标志设置”和程序的条件分支方法的代替方法,主要用于减少需要被测试的条件(分支条件)的次数。它通常只用于有意进行自修改的代码,而不适用于由于一个错误如缓冲区溢出而导致的意外修改其自身代码的情况。...
ANSYS WORKBENCH——参数化建模以及参数优化(结果导出为Excel)
目录 1、打开软件workbench 2、找到static structure,双击打开 3、选择材料 4、参数化建模 注:印记面的创建 5、模型属性设置 注:设置优化目标 6、回主界面,选择direct optimization模块 1、打开软件workbench 2、找到static structure,双击打开 3、选择材料 4、参数化建模 至此参数化建模就已经完成啦 注:印记面的创建 印记面一般是一个虚拟的区域,参与实际的网格划分,但是只是由于载.
DeepSeek + 微信:手把手教你把 AI 接入个人微信,秒变“高情商”聊天助手(防封指南)
将 DeepSeek 接入微信,本质上是给你的微信装了一个**“最强外挂”**。它不仅能帮你回消息,还能帮你写周报、查资料、甚至陪聊解闷。工具是服务于人的,不要让 AI 完全替代了你的真情实感。毕竟,真正的高情商,是屏幕背后那个在乎对方的你。先申请一个小号,按照步骤跑通流程。然后试着调整 Prompt,训练一个属于你自己的“嘴替”吧!
CTF逆向学习之SMC自修改
SMC是指:一种将可执行文件中的代码或数据进行加密,防止别人使用逆向工程工具对程序进行静态分析的方法,只有程序运行时才对代码和数据进行解 密,从而正常运行程序和访问数据。是一种程序在运行时修改自身代码的技术。然而,SMC 也带来了复杂性和潜在的安全风险,因此需要谨慎使用。SMC 的核心思想是程序在运行时修改自身的指令。
如何利用通达信进行选股集合操作
每个交易者实际上都有自己的选股策略,这是必然的,也会有自己的主观干预,但是还是需要从客观热点股票进行一个比对的,才能说主观和客观相结合不至于偏离方向。 这几天我也发了节前最后一天我的选股策略盘中的选择结果, 我也从网上拿到了热点股票池,当拿到之后你会发现如何从几十个股票热点股票选出核心票,这就是个问题了,这里面一定要通过股价涨跌幅来进行过滤,而不是通过指标,因为一切指标都是根据价格变化而改变的了,所以这一步不要走弯路。 1、把拿到的热点股票名单,导入通达信自定义板块 2、删除
微信小程序-收藏功能
给detail.wxml中的收藏图标添加属性: catchtap是点击事件,wx:if的用法如下: detail.js data: { detailObj:{}, index:null, // 是否收藏 isCollected:false }, handleCollection(){ let isCollected = !this.d...
大中型超市收银系统(可直接运行)
光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开
STM32F407中文手册
STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。
微信小程序实现收藏功能
我是个小菜鸟。。。。最近在学习一些微信小程序的知识,昨天写一个简单的收藏功能的时候遇到一些小错误,卡了很久。。。。在网上找答案的时候也找到很多实现的代码,但是我测试的时候还是会报错,后来终于发现了症结所在…555555555 这里贴一下我改之后的代码,如果有人有需要的话可以看看,因为我自己昨天真的找的很绝望…(也可能已经有大佬发过了,只是我没找到2333333) 修改之前的(昨天在网上找的示例代码...
最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版
Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。
微信小程序怎么实现收藏功能
小程序如何写收藏,分享,客服功能 收藏 页面中注册点击事件 <view class="goods_collect" bindtap="handleCollect"> <text class="iconfont {{isCollect?'icon-shoucang1':'icon-shoucang'}}"></text> <view class="collect_text">收藏</view> </view>
Devexpress16.2.6破解工具
Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具
微信小程序 实现点击收藏功能
自己刚接触小程序,在网上找了很多的收藏的代码,但是发现都点击收藏后,退出去再回来已收藏又变成未收藏状态,然后自己就改改改 拼拼凑凑终于改了出来 就是代码有些复杂 感觉可以更简便 但是我还没有找到方法 在这里记录一下 有大佬也可以指点一下 .wxml代码 <viewclass="save"> <textclass="saveText">{{isClick?'已收藏':'收藏'}}</text> <imagestyle="h...
小程序 收藏功能(storage)
思路:收藏首先分为 1.刚刚进入页面,判断本地缓存中是否有该类型的本地缓存(即判断是否是第一次进入小程序这个页面),在判断本地缓存中是否有这个商品的记录,有的话收藏图标变为收藏 2.点击收藏按钮更改本地缓存的数据,收藏即为true,否则false,同时修改本页面里的data里的isCollect(此变量控制html中收藏图标的变化) 3.模态框反馈收藏成功 本地存储的形式: 键对应值(值可以是对象...
25.微信小程序(组件--收藏案例)
微信小程序(组件–收藏案例) 前言 本节主要介绍下常见的收藏功能的实现 需求分析 样式分析: 未收藏时为灰色态,点击收藏按钮,图标变色,同时弹框实体收藏成功; 收藏成功后,点击已收藏的商品,取消收藏,此时图标恢复为灰色态,同时弹框提示取消收藏成功。 逻辑分析: 每个商品单独绑定个数据,负责管理收藏状态,点击时判断状态,然后切换 收藏功能 (1)先将图片静态样式写入 (1)先将图片静态样式写入 ...
微信 php收藏功能实现,关于微信小程序收藏功能的实现
这篇文章主要介绍了微信小程序收藏功能的实现代码,基本功能是点击收藏后显示已收藏,在另一个页面出现目前点击收藏的项目。需要的朋友可以参考下需求点击收藏后显示已收藏,在另一个页面出现目前点击收藏的项目需要解决的问题点击收藏后需要显示已收藏,并且文字状态改变另一个页面如何知道你点击了收藏,并且获得你点击收藏的数据如何解决?数据状态绑定,并且由状态控制样式(三元运算符)缓存(setStorageSync,...
小程序学习(5)——使用缓存storage来制作收藏效果
因为没有使用数据库,使用了一个数组制作数据文件,所以收藏效果也是以缓存的效果实现。
哔哩哔哩收藏夹备份程序mybili使用教程
哔哩哔哩收藏夹备份程序mybili使用教程 1. 项目介绍 mybili是一个开源的哔哩哔哩收藏夹备份程序。它可以帮助用户定期获取和备份哔哩哔哩上的收藏夹视频信息,包括视频标题、描述、封面等重要信息,并支持将视频下载到本地。通过mybili,用户可以避免因视频被删除或无法访问而丢失宝贵的收藏。 2. 项目快速启动 环境准备 Docker环境 Redis数据库 启动步骤 克隆项目到本地 gi...
安卓开发&裕语言程序---调用qq收藏作为远程更新实例
安卓开发&裕语言程序---调用qq收藏作为远程更新实例在裕语言环境下,做安卓个人开发的过程中,我们时有需要在软件内部实现动态远程公告更新,如果不采用传统方法,而改用QQ收藏来做,那么,如何实现呢?本次分享一下我自己在裕语言环境下实现用QQ搭建远程公告。(第一步)创建一个小程序(第二步) 进入程序,修改main页面的属性,最好一键删除(第三步)新建iyu界面(第五步)对iyu界面进行布局,进...
收藏夹程序的使用说明
轻巧的绿色收藏夹小程序
Ubuntu18.04 同一个程序显示两个图标,收藏夹图标不合并问题解决
同一个程序运行时的窗口图标与收藏夹图标不合并的问题: 在网上看到了很多都在复制粘贴别人的内容,都是让添加StartupWMClass,有时候这样并不会生效,而且网上都只说了桌面上的快捷方式.desktop文件()在/usr/share/applications下),可有时候收藏夹的图标在桌面上不一定就有快捷方式,比如我的pycharm是从“全部应用”那里直接右键收藏(全部应用列表里的.desktop文件在/usr/share/applications下)。 导致StartupWMClass不生效的原因: 网
5685



被折叠的 条评论
为什么被折叠?



