微信抢红包插件开发交流专帖

欢迎大家前来讨论交流,我研究两天了,目前有所收获,可以实现自动抢红包,但是还有些不够完美。需要和大家交流.

4 个赞

我主要使用了cycript工具来观察程序的结构,找到感兴趣的几个类
通过class-dump出来头文件,找到对应的类
主要类有
BaseMsgContentViewController,这个可以对应到群
WCPayC2CMessageNodeView, 这个红包cell的contentview的subview
WCRedEnvelopesReceiveHomeView,这个是点击红包cell出来一个居中的框,上面还有个拆红包按钮

接受消息是BaseMsgContentViewController实现这个方法

  • (void)MessageReturn:(unsigned int)arg1 MessageInfo:(NSDictionary *)arg2 Event:(unsigned int)arg3;

点击红包,会调用BaseMsgContentViewController的tapAppNodeView:方法

目前思路就是

%hook BaseMsgContentViewController

- (void)MessageReturn:(unsigned int)arg1 MessageInfo:(NSDictionary *)arg2 Event:(unsigned int)arg3
{
	%orig;

	UITableView *tableView = [self valueForKey:@"m_tableView"];
	NSArray *cells = [tableView visibleCells];
	for (UITableViewCell *cell in cells) {
		for (UIView *view in cell.contentView.subviews) {
			NSLog(@"+++++++++++++ %@", view);
			if ([view isKindOfClass:%c(WCPayC2CMessageNodeView)]) {
				NSLog(@"============== %@", view);
				WCPayC2CMessageNodeView *v = (WCPayC2CMessageNodeView *)view;
				[v performSelector:@selector(onClick)];		// 模拟点击的操作,会调用下面的tapAppNodeView:方法;
				break;
			}
		}
	}
}


- (void)tapAppNodeView:(WCPayC2CMessageNodeView *)arg1
{
//	%c(CMessageNodeData);
//	CMessageNodeData *node = [self findNodeDataByView:arg1];
//	[node GetNodeViewType];

	%orig;
}

%end

%hook WCRedEnvelopesReceiveHomeView

- (void)refreshViewWithData:(id)arg1
{
	%orig;
	[self performSelector:@selector(OnOpenRedEnvelopes)];
	[self performSelector:@selector(OnCancelButtonDone)];
}

%end

我想说和我写的差不多。。。

请问怎么判断红包抢过没呀?

不用判断,我是取了一个巧,就是我只取最后一个cell看他是不是红包的cell,是的话调用onclick,如果抢了之后,微信下面会多一行cell显示你已经领取了红包,所以在进去最后一行的cell就不会是红包的cell,也就不会再执行那个onclick了

我突然发现我们的思路完全不同,不过我感觉我这个应该要好一点,给你看看代码

%hook BaseMsgContentViewController

%new
- (id)someValue {
	return objc_getAssociatedObject(self, @selector(someValue));
}
 
%new
- (void)setSomeValue:(id)value {
	objc_setAssociatedObject(self, @selector(someValue), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

%end

%hook BaseMsgContentViewController

- (id)tableView:(id)arg1 cellForRowAtIndexPath:(id)arg2
{
	UITableViewCell *cell = %orig(arg1,arg2);
	NSIndexPath *indexpath = arg2;
  NSString *value = [self performSelector:@selector(someValue)];
  if(indexpath.row + 1 == [value integerValue])
  {
  	for (id subView in cell.contentView.subviews)
  	{
  		if([NSStringFromClass([subView class]) isEqualToString:@"WCPayC2CMessageNodeView"])
    	{    	
	   		[subView performSelector:@selector(onClick)];
   		}
  	}
  }
	return cell;
}

- (long long)tableView:(id)arg1 numberOfRowsInSection:(long long)arg2
{
	long long result = %orig(arg1,arg2);
	[self performSelector:@selector(setSomeValue:) withObject:[NSString stringWithFormat:@"%zd",result]];
	return result;
}

%end

%hook WCPayC2CMessageNodeView

%new
- (id)timer {
	return objc_getAssociatedObject(self, @selector(timer));
}
 
%new
- (void)setTimer:(id)value {
	objc_setAssociatedObject(self, @selector(timer), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

%end

%hook WCPayC2CMessageNodeView

- (void)onClick
{
	%orig;
	NSTimer *timeer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(find) userInfo:nil repeats:YES];
	[self performSelector:@selector(setTimer:) withObject:timeer];
}

%end

%hook WCPayC2CMessageNodeView
%new

- (void)find
{
		UIApplication *app = [UIApplication sharedApplication];
    UIWindow *keyWindow = app.keyWindow;
    for (id subView in keyWindow.subviews)
    {
      if([NSStringFromClass([subView class]) isEqualToString:@"WCRedEnvelopesReceiveHomeView"])
      {
        [subView performSelector:@selector(OnOpenRedEnvelopes)];
        NSTimer *timer = [self performSelector:@selector(timer)];
        [timer invalidate];
      }
    }
}

%end
1 个赞

非常感谢,我先研究研究

说下我的思路吧,有点奇葩,我是判断cell刷新的时候最后一个cell是不是红包cell如果是的话调用onclick方法,这个时候应该会请求网络来创建一个View,但是我无法判断这个view是什么时候出现,于是我就开了一个定时器一秒刷20次,来看这个view出现没,出现了就调用拆红包的方法,基本没问题,希望有更好的想法能交流下

可以直接hook那个view呀,就是这个WCRedEnvelopesReceiveHomeView

基本上hook这个方法就可以了

%hook WCRedEnvelopesReceiveHomeView

(void)refreshViewWithData:(id)arg1
{
%orig;
[self performSelector:@selector(OnOpenRedEnvelopes)];
[self performSelector:@selector(OnCancelButtonDone)];
}
%end

不错不错,当时没仔细看到这个方法

菜鸟问个问题,怎么知道有人发了红包呢?!以前看人说过是监听系统推送,然后判断是不是红包的,如果是就执行打开红包的操作,不知道楼主是怎么实现的。

暂时还不能根据消息判断是不是红包,只是根据cell的内容来判断的

你们都还停留在UI层;其实再往下一层,到逻辑层,就可以看到逻辑上微信接受到一条消息时的回调函数,如果在那个层面操作,就可以不用判断cell类型之类的东西,而专注在消息本身了。
(提示:如果遇到了CMessageMgr这个类,就说明方向对了)

3 个赞

狗神66的~

刚研究,还请多多指导

大家目前讲的都是自动抢红包,有没有什么思路可以抢到最大或者略大一点的红包?

看看随机的算法是怎么实现的?

服务器决定的

狗神还有个小问题,收到红包消息包时,怎么拿到发送者的昵称,而不是微信号