mirror of
https://github.com/Sunnyyoung/WeChatTweak-macOS.git
synced 2025-08-23 18:36:07 +08:00
Initial commit
This commit is contained in:
commit
b6c7ba03ec
113
.gitignore
vendored
Normal file
113
.gitignore
vendored
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
# Created by https://www.gitignore.io/api/macos,windows,sublimetext,visualstudiocode,xcode
|
||||||
|
|
||||||
|
### macOS ###
|
||||||
|
*.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
|
||||||
|
# Icon must end with two \r
|
||||||
|
Icon
|
||||||
|
# Thumbnails
|
||||||
|
._*
|
||||||
|
# Files that might appear in the root of a volume
|
||||||
|
.DocumentRevisions-V100
|
||||||
|
.fseventsd
|
||||||
|
.Spotlight-V100
|
||||||
|
.TemporaryItems
|
||||||
|
.Trashes
|
||||||
|
.VolumeIcon.icns
|
||||||
|
.com.apple.timemachine.donotpresent
|
||||||
|
# Directories potentially created on remote AFP share
|
||||||
|
.AppleDB
|
||||||
|
.AppleDesktop
|
||||||
|
Network Trash Folder
|
||||||
|
Temporary Items
|
||||||
|
.apdisk
|
||||||
|
|
||||||
|
|
||||||
|
### Windows ###
|
||||||
|
# Windows thumbnail cache files
|
||||||
|
Thumbs.db
|
||||||
|
ehthumbs.db
|
||||||
|
ehthumbs_vista.db
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
Desktop.ini
|
||||||
|
|
||||||
|
# Recycle Bin used on file shares
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
|
# Windows Installer files
|
||||||
|
*.cab
|
||||||
|
*.msi
|
||||||
|
*.msm
|
||||||
|
*.msp
|
||||||
|
|
||||||
|
# Windows shortcuts
|
||||||
|
*.lnk
|
||||||
|
|
||||||
|
|
||||||
|
### SublimeText ###
|
||||||
|
# cache files for sublime text
|
||||||
|
*.tmlanguage.cache
|
||||||
|
*.tmPreferences.cache
|
||||||
|
*.stTheme.cache
|
||||||
|
|
||||||
|
# workspace files are user-specific
|
||||||
|
*.sublime-workspace
|
||||||
|
|
||||||
|
# project files should be checked into the repository, unless a significant
|
||||||
|
# proportion of contributors will probably not be using SublimeText
|
||||||
|
# *.sublime-project
|
||||||
|
|
||||||
|
# sftp configuration file
|
||||||
|
sftp-config.json
|
||||||
|
|
||||||
|
# Package control specific files
|
||||||
|
Package Control.last-run
|
||||||
|
Package Control.ca-list
|
||||||
|
Package Control.ca-bundle
|
||||||
|
Package Control.system-ca-bundle
|
||||||
|
Package Control.cache/
|
||||||
|
Package Control.ca-certs/
|
||||||
|
bh_unicode_properties.cache
|
||||||
|
|
||||||
|
# Sublime-github package stores a github token in this file
|
||||||
|
# https://packagecontrol.io/packages/sublime-github
|
||||||
|
GitHub.sublime-settings
|
||||||
|
|
||||||
|
|
||||||
|
### VisualStudioCode ###
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
|
||||||
|
|
||||||
|
### Xcode ###
|
||||||
|
# Xcode
|
||||||
|
#
|
||||||
|
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
|
||||||
|
|
||||||
|
## Build generated
|
||||||
|
build/
|
||||||
|
DerivedData/
|
||||||
|
|
||||||
|
## Various settings
|
||||||
|
*.pbxuser
|
||||||
|
!default.pbxuser
|
||||||
|
*.mode1v3
|
||||||
|
!default.mode1v3
|
||||||
|
*.mode2v3
|
||||||
|
!default.mode2v3
|
||||||
|
*.perspectivev3
|
||||||
|
!default.perspectivev3
|
||||||
|
xcuserdata/
|
||||||
|
|
||||||
|
## Other
|
||||||
|
*.moved-aside
|
||||||
|
*.xccheckout
|
||||||
|
*.xcscmblueprint
|
||||||
|
|
||||||
|
# End of https://www.gitignore.io/api/macos,windows,sublimetext,visualstudiocode,xcode
|
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2016 Sunnyyoung
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
48
Makefile
Normal file
48
Makefile
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
WECHATPATH=/Applications/WeChat.app/Contents/MacOS
|
||||||
|
|
||||||
|
build::
|
||||||
|
clang -dynamiclib ./WeChatHook.m -fobjc-link-runtime -current_version 1.0 -compatibility_version 1.0 -o ./WeChatHook.dylib
|
||||||
|
|
||||||
|
debug::
|
||||||
|
make build
|
||||||
|
DYLD_INSERT_LIBRARIES=./WeChatHook.dylib ${WECHATPATH}/WeChat &
|
||||||
|
|
||||||
|
install::
|
||||||
|
@if ! [[ $EUID -eq 0 ]]; then\
|
||||||
|
echo "This script should be run using sudo or as the root user.";\
|
||||||
|
exit 1;\
|
||||||
|
fi
|
||||||
|
@if ! [ -f "${WECHATPATH}/WeChat" ]; then\
|
||||||
|
echo "Can not find the WeChat.";\
|
||||||
|
exit 1;\
|
||||||
|
fi
|
||||||
|
@if ! [ -f "./WeChatHook.dylib" ]; then\
|
||||||
|
echo "Can not find the dylib file, please build first.";\
|
||||||
|
exit 1;\
|
||||||
|
fi
|
||||||
|
|
||||||
|
@cp ${WECHATPATH}/WeChat ${WECHATPATH}/WeChat.bak;
|
||||||
|
@cp ./WeChatHook.dylib ${WECHATPATH}/WeChatHook.dylib;
|
||||||
|
@./insert_dylib @executable_path/WeChatHook.dylib ${WECHATPATH}/WeChat ${WECHATPATH}/WeChat --all-yes;
|
||||||
|
@echo "Install successed!";
|
||||||
|
|
||||||
|
uninstall::
|
||||||
|
@if ! [[ $EUID -eq 0 ]]; then\
|
||||||
|
echo "This script should be run using sudo or as the root user.";\
|
||||||
|
exit 1;\
|
||||||
|
fi
|
||||||
|
@if ! [ -f "${WECHATPATH}/WeChat" ]; then\
|
||||||
|
echo "Can not find the WeChat.";\
|
||||||
|
exit 1;\
|
||||||
|
fi
|
||||||
|
@if ! [ -f "${WECHATPATH}/WeChat.bak" ]; then\
|
||||||
|
echo "Can not find the WeChat backup file.";\
|
||||||
|
exit 1;\
|
||||||
|
fi
|
||||||
|
|
||||||
|
@rm -rf ${WECHATPATH}/WeChatHook.dylib;
|
||||||
|
@mv ${WECHATPATH}/WeChat.bak ${WECHATPATH}/WeChat;
|
||||||
|
@echo "Uninstall successed";
|
||||||
|
|
||||||
|
clean::
|
||||||
|
rm -rf ./WeChatHook.dylib
|
33
README.md
Normal file
33
README.md
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# WeChatHook-macOS
|
||||||
|
|
||||||
|
A dynamic library hook for WeChat macOS.
|
||||||
|
|
||||||
|
## Screenshot
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Feature
|
||||||
|
|
||||||
|
- Prevent message revoked
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
- `sudo make install` Inject the dylib to `WeChat` by [insert_dylib](https://github.com/Tyilo/insert_dylib)
|
||||||
|
- `sudo make uninstall` Uninstall the injection.
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
**Requirement: Command Line Tools**
|
||||||
|
|
||||||
|
Run `xcode-select --install` to install Command Line Tools.
|
||||||
|
|
||||||
|
- `make build` Build the dylib file to the same dicrectory.
|
||||||
|
- `make debug` Build the dylib file and run `WeChat` with dynamic injection.
|
||||||
|
- `make clean` Clean output files.
|
||||||
|
|
||||||
|
## Dependency
|
||||||
|
|
||||||
|
- [insert_dylib](https://github.com/Tyilo/insert_dylib)
|
||||||
|
|
||||||
|
## License
|
||||||
|
The [MIT License](LICENSE).
|
BIN
Screenshot/WeChatHook-macOS.png
Normal file
BIN
Screenshot/WeChatHook-macOS.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
BIN
WeChatHook.dylib
Executable file
BIN
WeChatHook.dylib
Executable file
Binary file not shown.
25
WeChatHook.m
Executable file
25
WeChatHook.m
Executable file
|
@ -0,0 +1,25 @@
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <objc/runtime.h>
|
||||||
|
#import <objc/message.h>
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
__attribute__((constructor))
|
||||||
|
static void initializer(void) {
|
||||||
|
Class messageServiceClass = NSClassFromString(@"MessageService");
|
||||||
|
SEL onRevokeMsgSEL = NSSelectorFromString(@"onRevokeMsg:");
|
||||||
|
IMP hookIMP = imp_implementationWithBlock(^(id self, id arg) {
|
||||||
|
NSString *message = (NSString *)arg;
|
||||||
|
NSRange begin = [message rangeOfString:@"<replacemsg><![CDATA["];
|
||||||
|
NSRange end = [message rangeOfString:@"]]></replacemsg>"];
|
||||||
|
NSRange subRange = NSMakeRange(begin.location + begin.length,end.location - begin.location - begin.length);
|
||||||
|
|
||||||
|
NSString *informativeText = [message substringWithRange:subRange];
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
NSUserNotification *userNotification = [[NSUserNotification alloc] init];
|
||||||
|
userNotification.informativeText = informativeText;
|
||||||
|
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:userNotification];
|
||||||
|
});
|
||||||
|
});
|
||||||
|
Method originMethod = class_getInstanceMethod(messageServiceClass, onRevokeMsgSEL);
|
||||||
|
IMP originImp = class_replaceMethod(messageServiceClass, onRevokeMsgSEL, hookIMP, method_getTypeEncoding(originMethod));
|
||||||
|
}
|
BIN
insert_dylib
Executable file
BIN
insert_dylib
Executable file
Binary file not shown.
Loading…
Reference in New Issue
Block a user