当前时讯:利用活跃变量分析来去掉vmp的大部分垃圾指令 活跃性计算的方法
声明:为了把技术分享给更多的人,在 大神论坛上发表了,这里也发一份 环境和工具 Windows7 7601 Ida7.5 Python3.8 qiling框架
简介 首先简单介绍一下数据流分析和活跃变量分析。活跃变量分析属于数据流分析的一种,编译器的许多优化都依赖于数据流分析。龙书的简介截图如下
(资料图片)
活跃变量分析的用途有删除无用赋值和为基本块分配寄存器。vmp 中的垃圾指令大部分都是些无用赋值,我们可以利用活跃变量分析来删除这些垃圾指令 如上图所示。如果把test指令看作是对eflags寄存器的赋值,其中的test指令就属于无用赋值,因为eflags寄存器在当前指令被赋值之后没有被使用,在下一条指令又被重新赋值。0064D721处对ebp的赋值在0064D748之前也没有被使用,也是一个无用赋值。
记录基本块 此次活跃变量分析仅局限于合并直接跳转后的基本块内,不做全局的数据流分析,可以不用添加前驱和后继,相当于做局部优化。本次使用的样本是vmp3.5版本加的壳,只点了虚拟化,没有做其它的处理,这个样本的源码在vmprotect3.5安装目录下Example\Code Markers\MSVC。以去除vmp1段中的垃圾代码为例,也就是加壳后程序入口点处的那部分虚拟机代码。由于vmp3.5展开了dispatch结构,并且利用间接跳转干扰静态分析工具的控制流重建。比如vmp使用大量的jmp register和push register; ret;等指令。为了构建控制流,我使用qiling框架来模拟执行来记录这类指令的跳转目标。qiling实现了一个pe加载器且模拟了部分系统api。经过验证,是可以运行到原程序的入口点。有两个api需要自己添加模拟,GetProcessAffinityMask和SetThreadAffinityMask。模拟的代码如下:
@winsdkapi(cc=STDCALL, dllname="kernel32_dll", replace_params={"lpProcessAffinityMask":POINTER, "lpSystemAffinityMask":POINTER }) def hook_GetProcessAffinityMask(ql, address, params): lpProcessAffinityMask = params["lpProcessAffinityMask"] lpSystemAffinityMask = params["lpSystemAffinityMask"] if(ql.mem.is_mapped(lpProcessAffinityMask, 4)): ql.mem.write(lpProcessAffinityMask,ql.pack32(1)) else: print("GetProcessAffinityMask->lpProcessAffinityMask(0x%08x) unmapped!" % lpProcessAffinityMask) addr = ql.os.heap.alloc(4) ql.mem.write(addr,ql.pack32(1)) if(ql.mem.is_mapped(lpSystemAffinityMask, 4)): ql.mem.write(lpSystemAffinityMask,ql.pack32(1)) else: print("GetProcessAffinityMask->lpSystemAffinityMask(0x%08x) unmapped!" % lpSystemAffinityMask) addr = ql.os.heap.alloc(4) ql.mem.write(addr,ql.pack32(1)) return 1@winsdkapi(cc=STDCALL, dllname="kernel32_dll", replace_params={"dwThreadAffinityMask":POINTER, }) def hook_SetThreadAffinityMask(ql, address, params): hThread = params["hThread"] pdwThreadAffinityMask = params["dwThreadAffinityMask"] if(ql.mem.is_mapped(pdwThreadAffinityMask, 4)): mask = ql.unpack32(ql.mem.read(pdwThreadAffinityMask, 4)) print("SetThreadAffinityMask(0x%08x, 0x%08x)" % (hThread,mask)) return 1
然后利用qiling的hook_code的回调函数来跟踪指令的走向,记录所需的跳转信息。回调函数的部分代码如下:
def traceCode(ql, address, size, user_data=None): #print("trace address:0x%08x" % address) #trace = [address,size] #if(trace not in g_traceAddrList): #g_traceAddrList.append(trace) if(0x004012F5 == address): #真正的入口点 print("execute to original entrypoint! address:0x%08x" % 0x004012F5) ql.emu_stop() #push reg;ret if(1 == size and ql.mem.read(address,size)[0] == 0xc3): target = ql.unpack32(ql.mem.read(ql.reg.esp, 4)) if(None != g_RetAddrDict.get(address)): g_RetAddrDict[address].add(target) else: g_RetAddrDict[address] = {target} md = ql.disassember md.detail = True bInsn = ql.mem.read(address,size) insn = list(md.disasm(bInsn, address))[0] #trace jmp Reg if(capstone.x86_const.X86_INS_JMP == insn.id and capstone.x86_const.X86_OP_REG == insn.operands[0].type): target = ql.reg.read(insn.operands[0].reg) if(None != g_jmpRegAddrDict.get(address)): g_jmpRegAddrDict[address].add(target) else: g_jmpRegAddrDict[address] = {target}
由于qiling框架模拟执行的有点慢,所以模拟到入口点结束后就把获取到的信息通过json序列化保存到了文件中。代码和文件我都会上传,这里就不用一一展开了。获取到信息后,就要记录所有的基本块。大体思路是以入口点的代码为一个作为一个新的基本块的开始,然后不断的把后续指令加进去,直到碰到一个无条件跳转、条件跳转指令或其目的地址的指令为止。具体实现是从入口点开始扫描每一条指令,把push imm; call imm;当作直接跳转,不分析直接跳转后面的指令,继续从直接跳转的目的地址开始分析。需要注意的是push register;ret;和jmp register需要看成是含有多个分支的跳转。然后利用一个队列来保存待分析的基本块首地址,代码实现如下:
def GetVmp1BasicBlock(): EntryPoint = 0x400000 + 0x0037E533 insn = ida_ua.insn_t() qInsnAddr = queue.Queue() #保留待分析的跳转分支起始地址 qInsnAddr.put(EntryPoint) while(not qInsnAddr.empty()): ea = start_ea = qInsnAddr.get() if(IsRedundant(ea)): #已经加入基本块,不用在分析 continue #print("trace start_ea:0x%08x" % start_ea) #分析start_ea开始的基本块 while(ea != 0x006FDE0C): #0x006FDE0B为虚拟机出口 #print("\tea:0x%08x" % ea) InsnLen = ida_ua.decode_insn(insn, ea) if(0 == InsnLen): print("decode_insn(ea=0x%08x) failed!" % ea) return 0 if(insn.itype in g_callInsnList and insn.ops[0].type in g_immOprand): prevInsn = ida_ua.insn_t() prevAddr = ea - 5 #push immediate;占用5个字节 prevLen = ida_ua.decode_insn(prevInsn, prevAddr)#调用decode_prev_insn可能会失败 if(0 == prevLen): print("decode_insn(0x%08x) failed!" % prevAddr) return 0 #push xxx;call xxx;把call看出直接跳转 if(ida_allins.NN_push == prevInsn.itype and ida_ua.o_imm == prevInsn.ops[0].type): end_ea = ea + insn.size vbb = VMPBasicBlock(start_ea, end_ea, insn.ea) g_vmp1BlockList.append(vbb) AdjustBlockByJccTarget(insn.ops[0].addr) qInsnAddr.put(insn.ops[0].addr) #print("\tqInsnAddr.put(0x%08x)" % insn.ops[0].addr) else:#暂不分析其它类型的call ea = ea + insn.size continue break elif(insn.itype in g_jccInsnList): end_ea = ea + insn.size vbb = VMPBasicBlock(start_ea, end_ea, insn.ea) g_vmp1BlockList.append(vbb) qInsnAddr.put(end_ea) #jcc需要分析其后面的指令 #print("\tqInsnAddr.put(0x%08x)" % end_ea) jccTarget = insn.ops[0].addr AdjustBlockByJccTarget(jccTarget) qInsnAddr.put(jccTarget) #print("\tqInsnAddr.put(0x%08x)" % jccTarget) break elif(insn.itype in g_jmpInsnList): end_ea = ea + insn.size vbb = VMPBasicBlock(start_ea, end_ea, insn.ea) g_vmp1BlockList.append(vbb) if(insn.ops[0].type in g_immOprand): #不分析jmp immediate后面的指令 JmpTarget = insn.ops[0].addr AdjustBlockByJccTarget(JmpTarget) qInsnAddr.put(JmpTarget) #print("\tqInsnAddr.put(0x%08x)" % JmpTarget) elif(ida_ua.o_reg == insn.ops[0].type): #jmp reg; for JmpTarget in g_jmpRegDict[ea]: AdjustBlockByJccTarget(JmpTarget) qInsnAddr.put(JmpTarget) #print("\tqInsnAddr.put(0x%08x)" % JmpTarget) break elif(ida_allins.NN_retn == insn.itype):#主要是push reg;ret;指令,还有少部分跳入vmp1的ret end_ea = ea + insn.size vbb = VMPBasicBlock(start_ea, end_ea, insn.ea) g_vmp1BlockList.append(vbb) """ prevInsn = ida_ua.insn_t() prevInsnLen = ida_ua.decode_insn(prevInsn, ea - 1)#push占用一个字节 if(0 == prevInsnLen): break if(ida_allins.NN_push != prevInsn.itype or ida_ua.o_reg != prevInsn.ops[0].type): break """ if(None == g_RetAddrDict.get(insn.ea)): #会遍历到没有模拟执行过的ret指令,可能由条件分支指令造成的 print("warning:cannot find ret target! address:0x%08x" % insn.ea) break for JmpTarget in g_RetAddrDict[insn.ea]: #g_RetAddrDict的key为ret的地址 #if(0x004012F5 == JmpTarget):#0x004012F5为原入口点 # continue if(JmpTarget < 0x63b000 or JmpTarget > 0x820000):#vmp1 segment bound print("ret from 0x%08x to 0x%08x" % (ea, JmpTarget)) continue AdjustBlockByJccTarget(JmpTarget) qInsnAddr.put(JmpTarget) #print("\tqInsnAddr.put(0x%08x)" % JmpTarget) break else: ea = ea + insn.size """ L1: xxx; ... L2: xxx; ... L3 jcc; 当有一条先跳转到L2的指令时,后面又有一条跳转到L1的指令, 会出现L1到L2的块且包含L2到L3的块 """ if(IsRedundant(ea)): #检测到另一个块的起始地址 vbb = VMPBasicBlock(start_ea, ea, insn.ea) g_vmp1BlockList.append(vbb) break return 1
执行完后发现有7000多个这样的块,所以需要合并一下那些直接跳转的块,也方便之后做活跃变量分析。合并和添加前驱和后继的代码就不展示了,具体参考源码中的AddVMPBasicBlockPrevsAndSuccs和TryMergeBasicBlock两个函数。 活跃变量分析 合并基本块后就可以做活跃变量分析了,在和合并后基本块内做活跃变量分析可以把每一条指令看作是一个结点,寄存器看作一个变量,然后利用使用和定值信息计算进入结点和结点后的活跃信息。这里给出《现代编译原理-C语言描述》第10章活跃分析的一个例子,方便大家理解使用、定值和活跃性。
活跃性计算的方法如下:
按照上述方法计算后,会得到每一个结点的入口活跃信息和出口活跃信息。考虑到合并后的基本块有1700多个,如果按照上面的迭代方法计算的话会很慢,所以具体实现要优化一下,加快数据流分析。基本块内指令是线性执行的,不存在环和分支,活跃变量分析属于逆向数据流问题。如果能够安排每一个结点的计算都先于它的前驱,是可以通过对所有结点的一次遍历就能完成数据流分析,得到每一个结点的入口活跃和出口活跃信息。获取基本块内每一个指令的use和def信息的话,可以使用capstone CsInsn类的regs_access方法,这还可以获取到eflags寄存器。一开始是想使用ida的microcode API来实现的,但是我觉得ida提供的python接口不好用,没有提供针对一条指令的转换接口。 对合并后的基本块的分析思路如下: 1、首先利用capstone反汇编基本块内的指令,获取每一条指令的use和def信息。 2、从基本块的出口处的指令向入口计算每一条指令的出口活跃信息和入口活跃信息。 3、在获取到指令的活跃信息后,然后根据每一条指令的def信息,如果def中的所有变量都不属于出口活跃的,我们就可以删掉这条指令。 具体代码实现如下:
def OptimizeMergedBasicBlock(mvbb, IsRadical = False): cs_insnList = []#capstone.CsInsn cs_use = {} #key为cs_insnList的下标,value为使用的寄存器集合,对变量的任何使用都会使该变量成为活跃的 cs_def = {}#key为cs_insnList的下标,value为修改的寄存器集合,对变量的任何定值都会杀死该变量的活跃性 vbbId = mvbb.FirstVbbId index = 0 while(vbbId in mvbb.vbbIdList):#获取变量和定值信息 vbb = g_vmp1BlockList[vbbId] #print("vbbid %d:0x%08x - 0x%08x"%(vbb.block_id,vbb.start_ea,vbb.end_ea)) bCode = idc.get_bytes(vbb.start_ea, vbb.end_ea - vbb.start_ea) if(None == bCode): print("get_bytes(0x%08x,%d) failed!" % (vbb.start_ea, vbb.end_ea - vbb.start_ea)) return 0 for insn in g_md.disasm(bCode, vbb.start_ea): cs_insnList.append(insn) useList,defineList = insn.regs_access()#(list-of-registers-read, list-of-registers-modified)包括eflags cs_use[index] = {cs_extendRegTo32bit(cs_reg) for cs_reg in useList} cs_def[index] = {cs_extendRegTo32bit(cs_reg) for cs_reg in defineList} index += 1 if(len(vbb.succs) != 1): break vbbId = vbb.succs[0] """ for i in range(len(cs_insnList)): use_strList=[] def_strList=[] for cs_reg in cs_use[i]: use_strList.append(cs_insnList[i].reg_name(cs_reg)) for cs_reg in cs_def[i]: def_strList.append(cs_insnList[i].reg_name(cs_reg)) print("0x%08x %s %s;%r %r" % (cs_insnList[i].address, cs_insnList[i].mnemonic, cs_insnList[i].op_str, use_strList,def_strList)) """ bChanged = True cs_insnTempList=[] while(bChanged): bChanged = False Out= {} #In和Out的key为cs_insnList的下标 In = {} for i in range(len(cs_insnList)): Out[i]=set() In[i]=set() Exit = len(cs_insnList) if(not IsRadical): In[Exit] = {capstone.x86_const.X86_REG_EBP, capstone.x86_const.X86_REG_EDI, \ capstone.x86_const.X86_REG_ESI, capstone.x86_const.X86_REG_ESP, \ capstone.x86_const.X86_REG_EAX, capstone.x86_const.X86_REG_EBX, \ capstone.x86_const.X86_REG_ECX, capstone.x86_const.X86_REG_EDX} else: In[Exit] = {capstone.x86_const.X86_REG_EBP, capstone.x86_const.X86_REG_EDI, \ capstone.x86_const.X86_REG_ESI, capstone.x86_const.X86_REG_ESP,} #如果安排每一个结点的后继都先于该结点计算,则有可能只通过对所有结点的一次遍历就能完成数据流分析。 #由于基本块内是线性执行的,不存在分支和环,所以采用倒序 for i in range(len(cs_insnList)-1,-1,-1): nSucc = i+1 Out[i] |= In[nSucc] In[i] = cs_use[i] | (Out[i]-cs_def[i]) """ for i in range(len(cs_insnList)): in1=[] out1=[] for cs_reg in In[i]: in1.append(cs_insnList[i].reg_name(cs_reg)) for cs_reg in Out[i]: out1.append(cs_insnList[i].reg_name(cs_reg)) print("0x%08x in:%r out:%r" % (cs_insnList[i].address,in1,out1)) """ DelIdxList=[] for i in range(len(cs_insnList)): count = len(cs_def[i]) if(0 == count): #不处理没有产生定值的语句 continue for cs_reg in cs_def[i]: #某些指令会产生多个定值,比如sub指令会修改通用寄存器和eflags寄存器 if(cs_reg not in Out[i]): #所有产生的定值都不是出口活跃的,则删除 count -= 1 if(0 == count):#对于产生的定值不在Out集合中,则可以被删除 bChanged = True DelIdxList.append(i) i=0 cs_insnTempList = [] for index in range(len(cs_insnList)): if(index not in DelIdxList): #保留已有的use和def信息,并调整index cs_insnTempList.append(cs_insnList[index]) cs_use[i] = cs_use[index] cs_def[i] = cs_def[index] i += 1 else: #删除对应的条目 cs_use.pop(index) cs_def.pop(index) ida_bytes.patch_bytes(cs_insnList[index].address,b"\x90"*cs_insnList[index].size) #g_cs_insnMnemonicSet.add(cs_insnList[index].mnemonic) cs_insnList = cs_insnTempList #print("cs_insnList len:%d" % len(cs_insnList)) """ for insn in cs_insnList: print("0x%08x %s %s" % (insn.address, insn.mnemonic, insn.op_str)) """ return 1
这里有几点需要说明一下,capstone的al,ah,ax等8位或16位的寄存器是单独定义的,需要转换到32位,因为vmp有8位或16位寄存器参与到下一个handle地址的运算。或者也可以把这些寄存器添加到In[Exit]中,添加In[Exit]是为了方便计算,作为整个基本块的出口活跃信息,不属于任意一条指令。把一些通用寄存器添加到基本块的出口活跃信息,也是为了保证不会nop掉有用的指令。那个IsRadical的判断主要是为了处理push imm;call target中target处的虚拟机入口。只添加ebp,esp,esi和edi作为整个基本块出口活跃信息是为了减少target处基本块没有nop掉的垃圾指令。在nop掉指令前,需要注意的是,编译器在删除死代码的优化中会考虑到当前被删除的指令是否有副作用,比如是否为访存指令、call指令等。本次样本中vmp的垃圾指令好像都没有副作用,不存在那些有副作用的指令,所以就没有考虑这些,nop完之后样本是可以正常运行的。最后在处理以下垃圾指令,直接遍历每一个基本块遇到这类指令直接nop掉。 这里展示一下入口处进入虚拟机那部分nop掉垃圾指令后的代码和部分x64dbg的trace截图
.vmp1:0064D713 56 push esi.vmp1:0064D714 90 nop.vmp1:0064D715 90 nop.vmp1:0064D716 90 nop.vmp1:0064D717 90 nop.vmp1:0064D718 90 nop.vmp1:0064D719 90 nop.vmp1:0064D71A 90 nop.vmp1:0064D71B 90 nop.vmp1:0064D71C 55 push ebp.vmp1:0064D71D 52 push edx.vmp1:0064D71E 51 push ecx.vmp1:0064D71F 9C pushf.vmp1:0064D720 90 nop.vmp1:0064D721 90 nop.vmp1:0064D722 90 nop.vmp1:0064D723 90 nop.vmp1:0064D724 90 nop.vmp1:0064D725 90 nop.vmp1:0064D726 50 push eax.vmp1:0064D727 90 nop.vmp1:0064D728 57 push edi.vmp1:0064D729 90 nop.vmp1:0064D72A 90 nop.vmp1:0064D72B 90 nop.vmp1:0064D72C 87 FF xchg edi, edi.vmp1:0064D72E 53 push ebx.vmp1:0064D72F 90 nop.vmp1:0064D730 90 nop.vmp1:0064D731 90 nop.vmp1:0064D732 90 nop.vmp1:0064D733 90 nop.vmp1:0064D734 66 0F A4 E7 8F shld di, sp, 8Fh.vmp1:0064D739 BA 00 00 00 00 mov edx, 0.vmp1:0064D73E 90 nop.vmp1:0064D73F 90 nop.vmp1:0064D740 90 nop.vmp1:0064D741 90 nop.vmp1:0064D742 90 nop.vmp1:0064D743 90 nop.vmp1:0064D744 90 nop.vmp1:0064D745 52 push edx.vmp1:0064D746 90 nop.vmp1:0064D747 90 nop.vmp1:0064D748 8B 6C 24 28 mov ebp, [esp+24h+arg_0].vmp1:0064D74C 81 ED 25 26 6F 1D sub ebp, 1D6F2625h.vmp1:0064D752 0F CD bswap ebp.vmp1:0064D754 90 nop.vmp1:0064D755 90 nop.vmp1:0064D756 90 nop.vmp1:0064D757 90 nop.vmp1:0064D758 90 nop.vmp1:0064D759 90 nop.vmp1:0064D75A 90 nop.vmp1:0064D75B F7 DD neg ebp.vmp1:0064D75D 90 nop.vmp1:0064D75E 90 nop.vmp1:0064D75F 90 nop.vmp1:0064D760 90 nop.vmp1:0064D761 90 nop.vmp1:0064D762 90 nop.vmp1:0064D763 90 nop.vmp1:0064D764 90 nop.vmp1:0064D765 90 nop.vmp1:0064D766 90 nop.vmp1:0064D767 90 nop.vmp1:0064D768 90 nop.vmp1:0064D769 90 nop.vmp1:0064D76A 90 nop.vmp1:0064D76B F7 D5 not ebp.vmp1:0064D76D 90 nop.vmp1:0064D76E 90 nop.vmp1:0064D76F 90 nop.vmp1:0064D770 90 nop.vmp1:0064D771 90 nop.vmp1:0064D772 81 ED 7B 53 BE 38 sub ebp, 38BE537Bh.vmp1:0064D778 90 nop.vmp1:0064D779 90 nop.vmp1:0064D77A 90 nop.vmp1:0064D77B 90 nop.vmp1:0064D77C 90 nop.vmp1:0064D77D 90 nop.vmp1:0064D77E 90 nop.vmp1:0064D77F C1 C5 03 rol ebp, 3.vmp1:0064D782 90 nop.vmp1:0064D783 90 nop.vmp1:0064D784 90 nop.vmp1:0064D785 90 nop.vmp1:0064D786 90 nop.vmp1:0064D787 90 nop.vmp1:0064D788 90 nop.vmp1:0064D789 8D 6C 15 00 lea ebp, [ebp+edx+0].vmp1:0064D78D 8B F4 mov esi, esp.vmp1:0064D78F 90 nop.vmp1:0064D790 90 nop.vmp1:0064D791 90 nop.vmp1:0064D792 90 nop.vmp1:0064D793 90 nop.vmp1:0064D794 90 nop.vmp1:0064D795 90 nop.vmp1:0064D796 90 nop.vmp1:0064D797 47 inc edi.vmp1:0064D798 81 EC C0 00 00 00 sub esp, 0C0h.vmp1:0064D79E 90 nop.vmp1:0064D79F 90 nop.vmp1:0064D7A0 90 nop.vmp1:0064D7A1 90 nop.vmp1:0064D7A2 90 nop.vmp1:0064D7A3 90 nop.vmp1:0064D7A4 90 nop
可以看到已经去掉大部分垃圾指令了,剩下的漏网之鱼也是很容易可以看出来的。
总结 根据实际运行效果,说明我的分析思路是大体正确的。这里没有根据基本块作为一个结点做全局的活跃变量分析是因为把通用寄存器作为活跃分析中的变量是不适合这么做的。因为通用寄存器的数量有限,是重复使用的资源,其活跃性很容易在下一个基本块被杀死。要做全局的活跃变量分析的话,应先把整个流图转换到SSA形式,这样应该可以干掉那些漏网之鱼了。考虑到工作量有点大,就没有这么做了(更多逆向分析资源请访问 大神论坛)。上传的源码中我也实现了一个获取合并后基本块的出口活跃和入口活跃信息的函数,不是SSA形式的。只是写来巩固一下自己所学知识点而已,对去除垃圾指令也没什么作用,大家有兴趣的话可以参考一下。也没有使用迭代的方法,而是做了一部分优化,通过工作表算法和对结点的深度优先搜索遍历序号进行计算的。代码实现在GlobalLiveness函数中。优化方法可以参考《现代编译原理-C语言描述》17章的加快数据流分析部分。
本文所有的分析文件和源码打包都在附件链接帖子末尾中 https://www.dslt.tech/article-97-1.html,欢迎下载交流学习,哈哈~~,更多逆向学习资料,可访问 大神论坛
版权声明:本文由 白云点缀的藍 原创,欢迎分享本文,转载请保留出处
标签:
相关推荐:
精彩放送:
- []乱码问题怎么解决?Ubuntu9.04上看电影加载中文字幕乱码问题
- []当前速读:吓唬的意思是什么?吓唬怎么造句?
- []稀奇古怪乐小米是什么?关于稀奇古怪乐小米的介绍
- []FASTQ格式是什么?FASTQ格式详情
- []北京民俗文化有哪些?关于北京民俗文化的介绍
- []天天报道:400-500分上的医科大学名单黑龙江 2023年参考医科大学录取名单
- []娱乐爆料:王丽坤、李冰冰、周杰伦、刘昊然、朱一龙
- []木格措海拔有多高?关于木格措海拔的介绍
- []最新资讯:JavaEE---Servlet入门教程 JavaEE操作步骤
- []环球热点!香茅是什么味道?香茅是什么植物?
- []焦点!版载千秋第3个隐藏任务怎么过?版载千秋答题器
- []世界时讯:苹果手机越狱后怎样恢复?苹果手机恢复回越狱前的方法
- []今日热门!使命召唤10下载地址是什么?使命召唤11中文版下载迅雷
- []最新:TSLAM9是什么?中心差分卡尔曼滤波
- []人均gdp是什么意思?人均gdp的含义
- []今日聚焦!大连市房产局官网怎么查询?大连市房产局官网
- []环球快看:搬砖是什么意思?dnf搬砖的含义
- []【环球速看料】ape音乐免费下载 ape音乐怎么下载?
- []外汇交易提醒:日元在震荡交投中回落,美元兑日元小幅反弹
- []当前播报:纹的组词有哪些?纹的组词有什么?
- []每日报道:DTA决赛放送:Z世代、元宇宙……酒旅业创新趋势都在这里 |
- []原油交易提醒:库存大降助力油价飙升超3%,警惕地缘局势不确定性风险上升
- []侨银股份预中标广州荔湾和莱州两个服务项目 总成交金额约1.79亿
- []天天播报:嘉兴嘉善2宗涉宅地6.16亿成交 三达房地产封顶价获其一
- []湖州德清一宗商住地将于明年1月11日出让 起始价3.48亿元
- []每日报道:2022年市场规模将超6000亿元 我国智能家居产业发展打开新空间
- []12月22日重点数据和大事件前瞻
- []每日热文:已有25家房企发布配股或定增 雅居乐第2次公告配售后股价跌超17%
- []湖南电力“满格” 水利显威
- []天天播报:年产首次突破50万吨 我国海上稠油热采实现“三级跳”
- []简讯:我国高端电力装备研发获重大成果
- []梅耶博格:开启29.6%效率的串联钙钛矿太阳能电池研发
- []焦点播报:EIA原油库存降幅超预期,美油短线拉升0.5美元
- []世界视点!5亿元!爱旭股份设立全资子公司投建6.5GW太阳能电池项目
- []每日速递:奥海科技:12月20日公司高管吴日诚的亲属减持公司股份合计300股
- []社保平均缴费指数怎么计算 怎么计算社保平均缴费指数
- []汉港控股3.4亿元向绿城服务租赁杭州余杭物业商业空间 租期十年
- []天天热头条丨一年扣一次大额什么意思 什么是一年扣一次大额
- []车险需要买哪些 购买一般车险要买什么险
- []世界观热点:皇庭国际第一大股东8698.59万股被司法拍卖 占总股本7.41%
- []世界即时看!金融街拟出售房山金悦嘉苑共有产权房项目,交易价22.6亿
- []天天亮点!央行:引导金融机构支持地产行业重组并购 防范化解头部房企风险
- []今日视点:央行:加大稳健货币政策实施力度 加大对民营小微企业支持力度
- []今日热议:嘉凯城聘任符谙、余薇为公司证券事务代表
- []速看:房地产开发板块跌0.75% 粤泰股份涨10.18%居首
- []当前讯息:康龙化成:12月20日公司高管楼小强减持公司股份合计4.47万股
- []每日观察!二手房周报 | 15城二手成交环比下降10%,北京规模已较高点腰斩(12.12-12.18)
- []世界滚动:宁波色母:12月20日公司高管祖万年减持公司股份合计5.25万股
- []环球观察:同有科技:12月20日公司高管杨建利减持公司股份合计7.01万股
- []环球快看点丨北京宸宇将向北辰实业与北京金隅归集资金共计2.5亿元
- []今亮点!郭施亮:为何房地产概念股走势频繁变脸?
- []环球看热讯:沈晓玲:房企年底为冲业绩,推“无理由退房”等靠谱吗?
- []明珠货运(YGMZ.US)以1500万美元收购飞鹏物流100%股权
- []每日动态!龙软科技:12月20日公司高管任永智、侯立、雷小平减持公司股份合计1.6万股
- []中科软:12月21日公司高管孙熙杰减持公司股份合计71.39万股
- []雄帝科技:公司暂时没有涉及该领域,对于新技术、新业态的发展公司会持续保持关注
- []昭衍新药:12月20日公司高管顾晓磊减持公司股份合计57.3万股
- []环球热文:宝新金融:立信德豪辞任 委任国富浩华为新核数师
- []【天天报资讯】第一服务:上海鼎晖耀家就保证回报权订立补充协议
- []新资讯:挂牌价24万/平重现,一线城市首现二手房参考价“隐退”
- []天天关注:中航机电:截至2022年12月20日,公司股东总户数为146,079户
- []当前视讯!江苏南通8宗涉宅地块46亿元成交
- []中公高科:12月20日公司高管李强减持公司股份合计3.86万股
- []昊华能源索赔案仍在征集中 涉诉金额合计已逾亿元
- []世界热点评!删除文件提示正在被另一程序使用怎么办?解决方法
- []速递!飞利浦吸尘器怎么样?维修中常见的问题
- []世界今日讯!天健集团成功发行11亿元超短期融资券 利率3.05%
- []环球关注:文本显示器的价格是多少?文本显示器的优势
- []全球快看点丨快速申请QQ靓号 教你用腾讯QQ极品靓号申请
- []环球微头条丨松下变频器怎么使用?松下变频器说明书详解
- []计算机网络虚拟局域网步骤 如何构建虚拟局域网?
- []全球看点:电脑蓝屏是什么原因?电脑蓝屏的解决方法
- []右脑记忆法的个人理解 王峰、袁文魁等记忆大师的通用方法
- []小学生电脑学习机有哪些?读书郎学生电脑主要功能
- []天天快看:什么是umd漫画制? umd漫画制作工具详情介绍
- []韩国泛泰手机怎么样?韩国泛泰手机参数配置如何?
- []联想轻薄笔记本怎么样?联想ThinkPad E325多少钱?
- []环球快讯:德国坦克声卡怎么样?德国坦克声卡质量好不好?
- []全球看热讯:CAD怎么建立三维模型? CAD的建模方法
- []什么是IGBT?IGBT是大功率元器件 属于绝缘型晶体管
- []环球资讯:解决win10邮箱无法登陆 163企业邮箱常见问题
- []股权投资基金的内部管理
- []环球热门:微信公众号的消息免打扰怎么打开?微信公众号的消息免打扰打开方法
- []信息:python十大培训有哪些?python十大培训详情介绍
- []环球观焦点:饮水机什么牌子质量好?饮水机品牌推荐
- []快资讯丨网络基础知识有哪些?网络基础知识大全
- []win7系统如何关闭系统默认共享文件夹?关闭系统默认共享文件夹方法
- []快资讯丨紫光电子平板电脑怎么样?紫光电子平板电脑如何刷机?
- []焦点资讯:预告片下载网站 如何在预告片电影中添加预告片?
- []环球资讯:生活真的不过如此吗? 听“体育评书”
- []世界观热点:iframe标签已经不见执行 如何解决?
- []小飞人熨斗怎样?小飞人熨斗特点介绍
- []全球观热点:OpenStreetMap Google 百度 Bing arcgis瓦片地图服务以及瓦片计算
- []【新视野】d3dx9_43.dll是什么丢失了怎么办?解决办法
- []【世界速看料】二手电视机有哪些分类?二手电视机分类介绍
- []如何清除AcadDoc.lsp病毒?AcadDoc.lsp病毒清理步骤
- []全球快资讯丨TP-LINK 忘记密码怎么办?恢复出厂设置
- []全球速讯:linux关闭tomcat日志打印 linux下打开与关闭tomcat
- []世界实时:C++扑克牌类的设计 C++扑克牌类怎么设计?
- []全球报道:基金收益怎么计算?基金收益计算器
- 环球观察:耶鲁大学耗时5年的研究成果 左脑与右脑的神奇功能研究
- 当前关注:Windows下【AxureRP】原型设计工具破解码与安装包 安装步骤
- 全球看点:关于葛晓非的介绍 你知道多少?
- 环球视讯!曲靖二中校长李舜荣:曲靖中统招生实际录取最低分数
- 观天下!针式打印机怎么调整打印范围?针式打印机调整打印位置的方法
- 焦点速讯:汽车钥匙丢了怎么办配一把多少钱?汽车钥匙丢了怎么补救?
- 潜行者是好人还是狼人?狼人杀潜行者角色什么功能?
- linux安装jdk8怎么装?手把手教你安装单机版Hadoop3.2.1
- 当前时讯:利用活跃变量分析来去掉vmp的大部分垃圾指令 活跃性计算的方法
- 【全球快播报】
百度云资源分享 百度云干货资源
- 一加手机怎么开启手电筒?一加手机开启手电筒操作步骤
- 产品报价单模板 制作报价时格式和细节
- 【天天新要闻】工程师必知:IP协议和IP地址是什么关系?
- 【全球速看料】2021年江苏高考成绩查询网址及查分方式
- 世界看点:立方体的体积怎么计算?计算方法
- 弘扬雷锋精神走进新时代 携手走向中华民族的伟大复兴
- 证监会:允许房地产和建筑等密切相关行业上市公司实施涉房重组
- 热点聚焦:德信中国2.68亿股配售事项及认购事项已达成 所得款项净额2.31亿港元
- 新消息丨德信地产集团目前已交付25个批次 总计交付近2万套
- 看点:德展健康:公司及控股子公司主营产品为心脑血管领域,目前公司在销产品中不包括上述产品
- 【环球聚看点】建发股份:厦门钟宅畲族社区旧村改造部分土地已出让 总价21亿
- ST华英:根据中国登记结算公司主动下发的数据,截止2022年12月20日公司股东户数为32,811户
- 今日热讯:丰原药业:产品价格受市场供求变化影响。公司子公司利康制药扑热息痛当前价格虽有上升,但没有较大变化
- 上实城开:收购跃成全部发行股本先决条件均已达成
- 焦点观察:盛和资源:公司与VHM公司签署了谅解备忘录,但尚未达到应予披露的标准
- 每日讯息!中国交通建设200亿元公司债券已获受理
- 环球热点评!滔搏:第三季度零售及批发业务总销售金额同比录得10%-20%下跌
- 华峰铝业:华青铝业为公司控股股东华峰集团参与投资的企业
- 热议:南极电商:公司授权有口罩,冰贴,消毒液等品类
- 报道:顾家家居股东持有的431万股股份解除质押 另有355万股股份质押
- 世界快资讯丨美亚光电:谢谢提问。根据中登结算公司下发的相关文件,截至12月20日收盘,公司股东数为22,823户
- 世界微动态丨“21长沙高新MTN001A”利率到期调整 由3.76%上调至4.90%
- 当前聚焦:青岛四批集中供地:40宗地全部出让收金约142亿元
- 哪些纸尿裤品牌值得购买呢,看看国际妈咪怎么说?
- 天津公积金新政:二套房贷款首付比例降至40%
- 【全球快播报】福建东百集团发行1亿元超短期融资券 利率5.40%
- 粤泰股份:关于上海宗美,目前公司共收到430万元回款,公司正向当地法院申请执行其部分资产
- 全球最资讯丨广东东莞国金大厦地块调整批前公示 将增加8.25万平米住宅供地等
- 世界微速讯:电投能源:发行价格将根据国资委和证监会有关规定确定,获得批复后,公司会努力早日完成发行
- 爱与责任同行,做难而正确的事!太平洋房屋荣膺“年度社会责任奖”!
- 当前焦点!金融街控股拟22.6亿元转让孙公司北京融嘉100%股权予华融基础
- 华融化学:公司不直接从事异质结电池业务
- 昊志机电:公司2022年度业绩情况以及相关案件进展情况请以公司后续披露的相关公告为准
- 1099元酒店隔离套票:无法随意出门,只能点外卖
- 大理遭遇大面积客房退单,春节预定量从80%下降到不足30%
- 焦点速讯:酒店业变革趋势:人工智能支持下的数字营销演化逻辑
- Cirium:航空市场复苏遇“气流颠簸”
- 全球动态:获年度品牌影响力大奖 合生创展的品牌力启示录
- 晨化股份:截止2022年12月20日公司股东人数约为1.78万人
- 12月21日煌上煌涨停分析:休闲食品,社区团购,新零售概念热股
- 12月21日南岭民爆涨停分析:民爆,湖南国企改革,国企改革概念热股
- 天天资讯:山东省:房企不得使用商业承兑汇票等非现金方式支付工程款
- 每日消息!12月21日人民网涨停分析:传媒,直播/短视频,彩票概念热股
- 恒大公布债务重组进展:分歧收窄 偿债资源是否能产生预期价值存在较大不确定性
- 天津公积金二套贷款首付由60%降至40%
- 天天关注:广东惠州:高层次人才公积金贷款额度可达100万元
- 焦点播报:12月21日友阿股份涨停分析:新零售,免税店概念,长寿药NMN概念热股
- 冠珠和金舵瓷砖哪个好?产品和服务给出答案
- 甜啦啦以鲜果茶,迎战全民大健康
- 浙东“绿色充电宝”宁海抽水蓄能电站双坝完工
- 长安汽车与宁德时代将组建动力电池合资公司
- 精选!比亚迪中标山东电工电气东营储能示范项目设备采购!
- 世界观点:锂电85%,液流电池70%!江西省能源局发文加强新型储能项目全过程管理
- 今日快讯:甘肃武威市与中国三峡新能源(集团)股份有限公司签署甘肃黄羊抽水蓄能电站项目投资开发协议
- 平安基金中标西安高新区保障房公募REITs基金管理服务项目
- 环球速看:城投鹏基拟于新疆参股成立城市运营管理公司 注册资本100万元
- 中原内配:截止2022年12月20日,公司股东总户数为59,962户
- 昆明垠创地产名下经典尚城二期法拍以底价约3.65亿成交
- 视焦点讯!“20红星05”持有人会议:将延长至2023年2月26日付息
- 消息!悦心健康:截止至2022年12月20日,公司股东总户数77,166户,机构总户数为792户
- 奕东电子:公司持续保持与客户的沟通,积极推进市场开发工作
- 当前焦点!百联东方商厦嘉定店因经营调整需要将于12月30日闭店
- 浔兴股份: 公司生产基于车间管理数据采集、处理辅助决策,提升管理效率
- 天天热议:容量补偿0.35元/度!补偿期不超过10年!内蒙古发文支持新型储能发展!
- 【天天播资讯】梅西为什么搭乘经济舱回国?
- 宁吉喆:明年必将迎来旅游业的恢复性增长热潮
- 两天销售额1.57亿元 宝企便携储能出海动能强劲
- 每日速递:多地更新峰谷电价政策 价差扩大打开储能等产业空间
- 环球百事通!国家电投发布900MWh储能设备电商化采购招标公告
- 亿嘉居住房地产底价1.34亿元竞得宜兴市一宗商住地
- 今日报丨强制转让!中国恒大减持7亿股恒大物业股权
- 全球关注:市值仅15亿 控股股东免费送7亿现金!上市公司再现花式“保壳” 交易所火速关注
- 全球今亮点!长江健康:阿胶是我国古老的名贵药材,具有补血滋阴,润燥,止血
- 滚动:普洛斯与中国联通加深战略合作 将深耕数字化基础设施发展
- 天天热点评!亿田智能:截止2022年12月20日股东总户数为8796户
- 【播资讯】脂肪肝“神药”来了,一个全新的百亿美元赛道?
- 当前最新:外汇交易提醒:日本央行意外调整国债收益率范围,日元暴涨近4%创四个月新高
- 【播资讯】河北石家庄投入超亿元资金促消费惠民生 提振消费信心
- 全球头条:酒店业备战元旦、春节传统旺季
- 全球热点!住房消费限制性政策被点名 限购、限贷松绑呼声最高
- 【全球速看料】顺腾国际控股拟1.25亿港元收购香港九龙物业
- 【全球热闻】12月21日重点数据和大事件前瞻
- 热资讯!11月武汉二手房价9连跌 10重点城市仅1地环比上涨
- 广州第四批集中供地收官:5宗地揽金191亿,保利95.8亿拿地
- 世界快看:深圳首个不限购“住宅”入市:每平方米近9万元,剩44年产权
- 全球热消息:油价“三连跌”收官 加一箱油将少花约18.5元
- 环球观热点:国家发改委:全国能源供需总体平稳有序
- 简讯:国际油价19日 上涨
- 公积金如何取出来用 如何将公积金取出来用
- 农行保险理财产品五年定期可以退吗 可以退农行保险理财产品五年定期吗
- 看热讯:学平险多久能理赔下来 学平险理赔要多久才能到账
- 全球播报:今日24时起 汽、柴油每吨降低480元和460元
- 当前信息:网上退保怎么办理流程 怎么办理网上退保
- 焦点讯息:大象转身!油气巨头收购7700MW风光项目!
- 最资讯丨中炬高新:控股股东中山润田所持1087万股因无人报价流拍
- 天天微资讯!美股异动 | 短视频营销服务商宝盛(BAOS.US)涨超21% 总市值约为832万美元
- 如何查询车辆保险是否到期 车辆保险是否到期如何查询
- 越秀房托1.26亿港元向越秀地产收购香港两项商业物业
- 头条焦点:百果园上市申请已通过聆讯 一个月前重新递交招股书
- ST开元收关注函 5000万元增资碳酸锂生产项目是否存在炒作