Inside Code Virtualizer

国央企创新负责人如何实现科技创新资源的系统化管理和高效配置?.docx 国央企创新负责人如何实现科技创新资源的系统化管理和高效配置? 立即下载
Written by Scherzo   


This article aim to explain how Code Virtualizer works. During the last month, I spent all my free time analysing the Code Virtualizer Demo 1.0.1.0 unpacked by softworm. Fortunately, I finished my analysis and I can say that this is the best software I have seen before. Not best in the meaning of protection, but in the meaning of organization. This was the most pleasing software I have analysed.

Three important things to notice are that the description and explanation of the code disassembled by OllyDbg is done in the code execution order. Most things that I am going to say are applicable only for the 1.0.1.0 version of Code Virtualizer. For comments on new versions, see "Hopes for the Future and Acknowledgments”. And I will not threat the 64-bit case.

This article is divided in two parts. Firstly I am going to talk about how the Virtual Machine is generated and why Oreans says that each Virtual Machine has its own characteristics. Secondly I use the concepts described before to explain how the Virtual Opcodes are generated, how they are executed and why they emulate the original code of an application.

Enjoy this article and I hope you learn something reading it.

Contents

1 Introduction
1.1 About Code Virtualizer
1.2 About this article
2 The Virtual Machine - Light VM
2.1 The Virtual Machine itself
2.2 Generating the Virtual Machine
3 The Virtual Opcodes
3.1 Disassembling and "Assembling" again
3.2 Generating and Writing the Virtual Opcodes
3.3 Completing the analysis: why does this really work?
4 Hopes for the Future and Acknowledgments
4.1 Why write this article?
4.2 The general attack approach
4.3 Acknowledgments

DISCLAIMER

ALERT: THIS ARTICLE MUST BE USED ONLY FOR SCIENTIFIC/STUDY PURPOSES. THE AUTHOR OF THIS ARTICLE IS NOT RESPONSIBLE FOR ANY USE OF THE KNOWLEGDE DESCRIBED HERE FOR ILLEGAL PURPOSES. YOU DO ARE ONLY ALLOWED TO READ THIS ARTICLE IF YOU AGREE WITH THIS DISCLAIMER.

1 Introduction

1.1 About Code Virtualizer

Code Virtualizer is a powerful code obfuscation system that helps developers protect their sensitive code areas against Reverse Engineering. Code Virtualizer has been designed to enact high security for your sensitive code while requiring minimal system resources.

Code Virtualizer will convert your original code into Virtual Opcodes that will be only understood by an internal Virtual Machine. Those Virtual Opcodes and the Virtual Machine itself are different for every protected application, avoiding a general attack over Code Virtualizer.

Code Virtualizer can protect your code in any x32 and x64 native PE files, like executable files (EXEs), system services, DLLs, OCXs, ActiveX controls, screen savers and device drivers[1].

1.2 About this article

First of all, I need to say sorry. Probably you will see a lot of mistakes because of my english but I hope you will understand me.

This article aim to explain how Code Virtualizer works. During the last month, I spent all my free time analysing the Code Virtualizer Demo 1.0.1.0 unpacked by softworm[2]. Fortunately, I finished my analysis and I can say that this is the best software I have seen before. Not best in the meaning of protection, but in the meaning of organization. This was the most pleasing software I have analysed.

Three important things to notice are that the description and explanation of the code disassembled by OllyDbg[3] is done in the code execution order. Most things that I am going to say are applicable only for the 1.0.1.0 version of Code Virtualizer. For comments on new versions, see "Hopes for the Future and Acknowledgments”. And I will not threat the 64-bit case.

This article is divided in two parts. Firstly I am going to talk about how the Virtual Machine is generated and why Oreans[4] says that each Virtual Machine has its own characteristics. Secondly I use the concepts described before to explain how the Virtual Opcodes are generated, how they are executed and why they emulate the original code of an application.

Enjoy this article and I hope you learn something reading it.

2 The Virtual Machine - Light VM

2.1 The Virtual Machine itself

I think you have noticed that I called this Virtual Machine as "Light VM”. Actually, not me but Oreans developers did that probably refering to the Themida Virtual Machine.

Basically each Virtual Machine has 150 handlers and a main handler. By handler, I mean a kind of function that will deal with the Virtual Opcodes. In general, they are small (one to six lines of assembly code) and it is really important to understand each one.

Next I will show the first structure that I called Handler_Information and an example of it (figure 1):

  • WORD id // a number that represents the handler

  • DWORD start // the address of the start of this handler in the Code Virtualizer file

  • DWORD end // the address of the end of this handler in the Code Virtualizer file

  • DWORD address // the address of the start of the handler in the protected file

  • WORD order // random number from (0Eh to A4h) that will indicate the place of the handler in the protected file



Figure 1:

Handler_Information structure example

PIC


This structure is the principal one to generate the VM. I will not show you each of the 150 handlers. This is tedious but if you want to study Code Virtualizer deeper, you must read and understand one by one. I will show you just the handler I showed in the figure above (figure 1; id = 0000h; start = 006035F0h; end = 006035F8h) and the main handler (figure 3):



Figure 2:

Handler 0000h

PIC




Figure 3:

Main Handler

PIC


There is a particularity in the main handler: you can see three times the DWORD 11111111h. They are different depending on the protected application. The first DWORD is the address of the seventh line of the main handler in the protected file. The second one is the "image base" of the Virtual Machine. The last DWORD is the total number of handlers in that VM.

2.2 Generating the Virtual Machine

Here I will give arguments to proof after that the phrase "Those Virtual Opcodes and the Virtual Machine itself are different for every protected application, avoiding a general attack over Code Virtualizer." is not a very important feature.

The first step done by Code Virtualizer is to write the main handler. Next the other 150 handlers will be written following the Handler_Information.order sequence from 1Eh to A4h. As Handler_Information.order is randomly generated the result will be a difference sequence of handlers for every protected application (if you want an example, see [5]).

Now I am going to explain how the handler 0000h (see figure 2) is written. The same process occurs for every handler.

The next step is showed by the code below:



Figure 4:

LODS special case

PIC


This piece of code looks for LODS instructions. This is not applicable for the handlers 0154h and 0156h. But why these checks? Well, the LODS instruction in a handler represents the reading of 1, 2 or 4 Virtual Opcodes. And to increase the security, Oreans developers insert random code after the LODS instruction. To do that, they use another structure that I have called Special_Handler. Here you are:

  • WORD Handler_Information.id // see Handler_Information structure

  • BYTE instruction3 // number that says what kind of instruction will be written as the third instruction

  • BYTE instruction2 // number that says what kind of instruction will be written as the second instruction

  • BYTE instruction1 // number that says what kind of instruction will be written as the first instruction

  • BYTE instruction4 // number that says what kind of instruction will be written as the fourth instruction

  • DWORD Random1 // random number that will be part of the instruction 2

  • DWORD Random2 // random number that will be part of the instruction 3


Table 1:

Table of possible random instructions. Each of these instructions can be written in DWORD, WORD or BYTE format using the respective registers ax, bx, al, bl.






instruction1

instruction2

instruction3

instruction4






0

sub eax,ebx

sub eax,Random1

sub eax,Random2

sub ebx,eax






1

add eax,ebx

add eax,Random1

add eax,Random2

add ebx,eax






2

xor eax,ebx

xor eax,Random1

xor eax,Random2

xor ebx,eax









Figure 5:

Example of Special_Handler structure

PIC


So before those operations, the handler 0000h (figure 2) will be like this:



Figure 6:

Handler 0000h before addition of 4 instructions

PIC


The next step is another security feature. Some kind of instructions are mutated by the Oreansf1.F4 function exported by Oreansf1.dll module. This means that the code of each handler will be obfuscated and more, this mutation engine is strictly related to the option Virtual Machine Obfuscation. Actually, this option only changes the complexity of the mutated opcode. This is really something strange because there is no difference if the complexity of the VM is low or highest in a general attack to Code Virtulizer (for more comments, see "Hopes for the Future and Acknowledgments").



Figure 7:

Handler 0000h with mutated opcodes

PIC


Before that, a JUMP to the main handler is written so the next handler will be called.

The next security feature is quite fun to see: all the 150 handlers are mixed randomly!!! For example, a piece of the handler 0161h is followed by a piece of the handler 0001h and the handler 0069h, etc...

So in the end there will be a complete obfuscated, unique and difficult code to be analysed. Really! I do not think so :).

3 The Virtual Opcodes

3.1 Disassembling and "Assembling" again

I know that the things are obscure. You probably still have no idea about how those handlers work but I promise that it will be clear in the section 3.3.

The figure below shows a macro not virtualized. The code that will be virtualized starts at 0040106Eh and ends at 0040107Dh.



Figure 8:

Macro not virtualized

PIC


Next a PUSH 0040108Dh and RET will be added to the original code so the program can continue its execution normally.

After that, the exported function Oreansf1.F1 disassembles the original code as you can see below. It was really a surprise to me when I saw that; I hoped that Code Virtualizer would threat the code through the bytes of the original code not through strings. It uses Delphi functions to threat strings and I think this is not the faster way but for sure it is easier.



Figure 9:

Code disassembled

PIC


Now the function OreansX2dllR.F1 exported by OreansX2dllR.dll will do the principal and most complex work of assemble the assembly code in a Code Virtualizer syntax and generate the most important structure that I have called OreansX2.

OreansX2 structure:

  • DWORD instruction // type of instruction following the Code Virtualizer syntax

  • DWORD sufix // sufix for the instruction

  • DWORD data1 // data for the instruction

  • DWORD data2 // data for the instruction

  • WORD unknown // unknown use


Table 2:

Table of possible instructions for OreansX2 structure



OreansX2.instruction

instruction



00

LOAD



01

STORE



02

MOVE



03

IFJMP



04

EXTRN



05

UNDEF



06

IMULC



07

ADC



08

ADD



09

AND



0A

CMP



0B

OR



0C

SUB



0D

TEST



0E

XOR



0F

MOVZX



10

MOVZX_W



11

LEA



12

INC



13

RCL



14

RCR



15

ROL



16

ROR



17

SAL



18

SAR



19

SHL



1A

SHR



1B

DEC



1C

NOP



1D

MOVSX



1E

MOVSX_W



1F

CLC



20

CLD



21

CLI



22

CMC



23

STC



24

STD



25

STI



26

HLT



27

BT



28

BTC



29

BTR



2A

BTS



2B

SBB



2C

MUL



2D

IMUL



2E

DIV



2F

IDIV



30

BSWAP



31

NEG



32

NOT



33

RET





Table 3:

Table of possible sufixes



OreansX2.sufix

sufix



00



01

ADDR



02

%sADDR, %d



03

%sADDR, %.8x%h



04

BYTE PTR %s[ADDR]



05

WORD PTR %s[ADDR]



06

DWORD PTR %s[ADDR]



07

QWORD PTR %s[ADDR]



08

%sBYTE PTR [%.8x%h]



09

%sWORD PTR [%.8x%h]



0A

%sDWORD PTR [%.8x%h]



0B

%sQWORD PTR [%.8x%h]



0C

ADDR, BYTE PTR %s[%.8x%h]



0D

ADDR, WORD PTR %s[%.8x%h]



0E

ADDR, DWORD PTR %s[%.8x%h]



0F

ADDR, QWORD PTR %s[%.8x%h]



10

%s%d



11

%s%.8x%h



12

reserved



13

reserved



14

reserved



15

reserved



16

reserved



17

reserved



18

BYTE



19

WORD



1A

DWORD



1B

QWORD



1C

reserved



1D

reserved



1E

FLAGS



1F

%s[ADDR]



20

%sBYTE %d



21

%sWORD %d



22

%sDWORD %d



23

%sQWORD %d




As you can see, the syntax is quite logic. It uses XOR, ADD, etc. for well known instructions and obvious names like MOVE, STORE, LOAD for "special" instructions; the sufixes use a single variable ADDR and well known formats like DWORD PTR [ADDR].

I still do not understand completely how those instructions are generated from the original code disassembled but I think that this is not a problem if you do some tests to see the pattern. Next I show you one assembly instruction followed by the equivalent block of Code Virtualizer instructions with their respective OreansX2 structure (see the file [5] for more examples).



Figure 10:

Example of Code Virtualizer syntax

PIC


I do not know if you have noticed it, but the first parameter of the first OreansX2 structure above is 80000002h. 02 means MOVE as you can see in the Table 2, but this 80 means that this instruction has a relative address. That is, the address F0000028h is relative to the image base of the Virtual Machine.

3.2 Generating and Writing the Virtual Opcodes

Having a vector of the OreansX2 structure, now a sequence of operations will be done to reach the next structure that I have called Pre_Handler. The size of this structure is 28h bytes.

  • DWORD counter // counter that is incremented by 0Eh for each Pre_Handler structure

  • DWORD real_opcode_mark // this DWORD is the address of the original opcode in an allocated memory. This is only applicable to the first Code Virtualizer instruction of the block of instructions that represent the original opcode

  • DWORD unknown1 // unknown use

  • DWORD counter_0E // this the Pre_handler.counter plus 0Eh (unknown use)

  • BOOL is_special // True if the original opcode is any kind of call, jump, conditional jump and others. In this case, a special structure will be generated for those instructions

  • BYTE instruction // Same as OreansX2.instruction

  • DWORD sufix // Same as OreansX2.sufix

  • DWORD data1 // Same as OreansX2.data1

  • DWORD data2 // Same as OreansX2.data2

  • WORD unknown2 // Same as OreansX2.unknown

  • 7 bytes unknown

  • BOOL is_relative_address // TRUE if the instruction has a relative address



Figure 11:

Example of Pre_handler structure

PIC


So now the principal structure that is directly related with the Virtual Opcodes generation can be studied. I have called this structure as Handler.

  • WORD handler // this is the principal parameter: it is the the one who will determine what handler must be called. It is equivalent to Handler_Information.id

  • DWORD Pre_Handler_addr // address in memory of the correspondent Pre_Handler structure that generated this Handler structure

  • DWORD memory_opcode // memory address of where the Virtual Opcode represented by this structure will be written

  • BYTE type_of_handler // 0 if the handler does not read Virtual Opcodes through LODS intrscution. 1, 2, 4, 8 if the handler reads 1, 2, 4, 8 Virtual Opcodes

  • BYTE unknown2 // unknown use

  • DWORD data1 // data for the Code Virtualizer instruction (like for example LOAD 18h, data1 will be 18h)

  • DWORD data2 // data for the case of 64-bit Code Virtualizer instrution

  • DWORD file_opcode // address in the protected file of where the Virtual Opcode represented by this structure will be written



Figure 12:

Example of Handler structure

PIC


Each Handler structure can generate 1, 2 or 4 Virtual Opcodes and that is a must to understand how the vector of Handler structures is generated.

This is not so complicated but if I put each case here, this article would be too big. So I will just comment how this works and if you want more details see [6].

Basically each vector of Handler structures starts with the handler 015Bh and ends with the handlers 0161h and 015Ch. The handlers 015Bh and 015CH do not exist actually. They are there just to tell Code Virtualizer that special code must be inserted to handle when the execution of Virtual Opcodes is initiated and when it is finished. This special code will be showed shortly.

Between those handlers the Pre_handler structure is threated like this: if Pre_handler.is_special is TRUE, the handler 0161h will be added to the correspondent Handler structure. After that, a different sequence of Handlers structures is generated for each of the cases: MOVE, LOAD, STORE, SHL, ADD, SUB, IFJMP, RET, UNDEF and default case (for the others Code Virtualizer instructions). You can see more details about those sequences in [6].

Having understood how the vector of Handler structures is generated, you can finally understand the brilliant part of Code Virtualizer: how the Virtual Opcodes are built.

The first thing to say is about when Code Virtualizer finds the handlers 015Bh and 015Ch. There is a pre-built virtualized code (this means that the Code Virtualizer instructions and the others structures are not there) that is responsible to initialize and unitialize the Virtual Machine for example, catching or returning the registers and flags before the protected application executes its Virtual Opcodes.

So now I am going to talk about the generation of Virtual Opcodes given the Handler structure. The first thing that Code Virtualizer does is quite surprising. Using a random number generator, it decides about the execution of a specific CALL. This CALL is responsible to generate "fake" Virtual Opcodes. That is, those Virtual Opcodes are going to be executed but they will not change anything in the program (like a sequence of NOPs) and so they are useful to obsfucate the real Virtual Opcodes. Besides, there are five different sequences of "fake" Virtual Opcodes difficulting even more the analysis of the program. And I say more, the option Virtual Opcode Obfuscation (low, normal, high, highest) is strictly related (I meant only related) with these "fake" Virtual Opcodes. Depending on that option, the chance of the random number generator allow the recursively execution of the specific CALL more than one time can be increased or decreased. So for example, in the middle of the emulation of a instruction, there can be a lot of "fake" Virtual Opcodes. They can increase the size of the Virtual Opcodes by a factor of 3!!!

Unless the "fake" Virtual Opcodes, you can say that the Virtual Opcodes would be identical if you protect an application twice and compare the Virtual Opcodes. What make them different, is a global variable in the Code Virtualizer that I have called key.

So if the handler 0010h must be called, given the Handler_Information.order and the Special_Handler structure (see section 2.1 and 2.2 for the explanation of these structures), the inverse operations of the ones described in Table 1 (that is ADD, SUB, XOR) will be executed to reach the correct Virtual Opcode. The things are a little confusing I think. So let’s clear them.

3.3 Completing the analysis: why does this really work?

The aim of this section is to explain step-by-step the initialization of the Virtual Machine and the execution of the Virtual Opcodes. To do that, I will use a file that I prepare and that does not have fragmented handlers and mutation engine[7].

When the protected application reaches a macro, the code is redirected to a PUSH/JMP sequence in a section created by Code Virtualizer.



Figure 13:

PUSH/JMP example

PIC


The value pushed is the address of the first Virtual Opcode and the jump is to the main handler.



Figure 14:

Virtual Opcodes

PIC




Figure 15:

Main Handler

PIC


The code started at 004072D8h is always called before the execution of every handler. It is responsible to call the handler specified by the Virtual Opcode. The key is initialized with the the address of the first Virtual Opcode and it is stored in the EBX register. The ESI register has the current address of the Virtual Opcode read and the EDI register has the Image base of the Virtual Machine. The stack is used to store values and the EAX register is used for operation like XOR, ADD, etc.

So when the code reaches the address 004072D8h, the registers are like this:



Figure 16:

Register in the Main Handler

PIC


Now the byte 62h is read and after some operation with the key (those random operations explained in the section 2.2; see figure 15), when the code reaches the address 004072E4h, the registers are like this:



Figure 17:

Jumping to handler 2Dh

PIC


As you can see, the key was changed and the ESI register was updated. Now the code jmp dword ptr ds:[edi+eax*4] seems obvious: as EDI has the image base of the Virtual Machine, the EAX value obtained from the Virtual Opcode plus some operation is very important to call the handler if you notice that there is a table of pointers to handlers:



Figure 18:

Piece of table of pointers to handlers

PIC


By now, you know how every handler is called and it is possible to explain why the Virtual Opcodes are unique for every protected application: because of the key. The key is changed a lot of times and it is address depedent. As the Virtual Opcodes depend on the key (see section 3.2 for explanation) and the size of the Virtual Machine is not constant, the Virtual Opcodes are unique.

The first two instructions of the Main Handler (PUSHAD and PUSHFD) push onto the stack the registers EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI and the Flags. After, the pre-built Virtual Opcodes that I have talked about are responsible to pop those registers in the first 38 bytes of the Virtual Machine. Now a instruction like XOR ECX, ECX will change the value in the address 00407014h. At the end of the execution of the virtualized code, the registers are restored in their correct position allowing the application to continue its execution.



Figure 19:

Virtual Machine registers

PIC


Now that is your time. I will not comment every executed line. I gave you the basis and I hope that the things are more clear now. So trace the example program [7] and understand how the others handlers are executed.

4 Hopes for the Future and Acknowledgments

4.1 Why write this article?

As I said in the disclaimer, the main purpose of this article is to transmit the knowledge that I have learned to you. Besides that, I need to say that I intended to write a tool instead of this article. And I have also started it but as I am not a programmer I saw that with the amount of free time that I will have I would not be able to write this tool.

So what I hope is that someone gets interest in writing this tool (just e-mail me). I can help and even provide source code of what I have coded until now. But be aware that this is not an easy work.

An important thing to say is that this is a very resumed article. I mean there is a lot of details that I omited (no time and so tired now to say them) and others details that I did not notice. If you have any questions or if you saw something wrong in my article or if you wants to improve this article just e-mail me.

And my main hope is to see a similar article about the Themida Virtual Machine. Let me say, this would not be too difficult now before this article mainly because Themida uses the same DLLs as Code Virualizer and because Oreans developers themselves told us that Code Virtualizer is a version of Themida Virtual Machine a little simpler (remember the Light VM).

And a word for Oreans: this is really a great tool to protect sensitive code areas but as you said not 100% safe (there is not anyone 100% safe). I think there is not a similar one in the market too good as this one. Keep your good job improving this software!

4.2 The general attack approach

So here I will comment my ideas about a tool to deal with Code Virtualizer and how to threat new versions. The toll is divided in three parts:

  • Preprocessing

    • Get all information about the file using the PEheader

    • Look for Virtual Machines

      • Fill the VM class with information about the Virtual Machine

      • Identify every handler

    • Look for Macros

      • Get the total size of the Virtual Opcodes

      • Find jumps to the macro. This is the place where the original code was

  • Analysis

    • Find the "fake" Virtual Opcodes and eliminate them

    • Retrieve the Code Virtualizer instructions

    • Analise them and retrieve the original code

  • Posprocessing

    • Save the original code in the correct place

    • Correct the PEheader

    • Save the file

The two most difficult things are to find and identify each handler in the Virtual Machine and to retrieve the original code from the block of Code Virtualizer intructions.

For the first thing I say, you have two options: study the mutation engine and do reverse engineering (very difficult); or as the mutation engine does not mutate all the opcodes I noticed that it is almost 100% possible to find each handler by their not mutated instructions.

For the second thing I say, you have two options: study how the Code Virtualizer instructions are generated from the original disassembled code and do reverse engineering (difficult); or do some tests with differents kind of instructions and see the pattern. By the way, a hint is that a very well recognizable handler is used always for every original instruction: the STORE FLAGS. This makes the work of find the number of original instructions easier.

This tool must support different versions of Code Virtualizer. As the structure of it does not change, you need to adapt a few things for example new handlers, modified handlers, and other things.

A fun example: commands like ADD, XOR, SHL, etc. have in general three handlers; one for the byte operation, one for the word and one for the dword. But when I first saw the three handlers for the SHL instruction I saw something very strange:



Figure 20:

Code Virtualizer bug

PIC


But only in the version 1.2.0.0 we saw: "[!] Fixed Virtualization of "SHL reg16, imm""[8]. Interesting, isn’t it?

4.3 Acknowledgments

I must say a big thanks to people who helped me directly and indirectly to write this article. So here you are:

  • Melvill, Portuogral, forgetoz and Spec0p (CRKTeam): people really important to me. They introduced me to the Reverse Engineering and helped me a lot. This article is especially dedicated to them.

  • softworm: well... what can i say? Without his really good job, this article would not exist.

  • Ricardo Narvaja and CrackSLatinoS: really good tutorials

  • The Reverse Engineering Community (the ones where I am active): CrkPortugal, ARTeam, Unpack.cn, Tuts4you, EXETOOLS

References

[1] Code Virtualizer Help File - Code Virtualizer Help.chm

[2] http://www.unpack.cn/viewthread.php?tid=5802&fpage=1&highlight=code%2Bvirtualizer

[3] OllyDbg v1.10 by Oleh Yuschuk - http://www.ollydbg.de/

[4] http://www.oreans.com/

[5] ../Annex/Example of Code Virtualizer instructions.rtf - this file is included in the file Inside Code Virtializer.rar

[6] ../Annex/Analysis of Code Virtualizer instructions - this folder is included in the file Inside Code Virtializer.rar

[7] ../Annex/handler.exe - this file is included in the file Inside Code Virtializer.rar

[8] http://www.oreans.com/CodeVirtualizerWhatsNew.php

国央企创新负责人如何构建面向科技成果转化的智能服务生态?.docx 国央企创新负责人如何构建面向科技成果转化的智能服务生态? 立即下载

相关推荐

电池、AA‑CAES 与抽水蓄能多目标优化调度研究(三目标:成本、峰谷差、碳排放)(Matlab代码实现)

内容概要:本文针对电池、先进绝热压缩空气储能(AA-CAES)与抽水蓄能三种储能技术,构建了一个多目标优化调度模型,旨在协同优化电力系统的运行成本、负荷峰谷差和碳排放三个关键指标。研究采用Matlab进行代码实现,建立了综合考虑各类储能系统运行特性的精细化数学模型,并通过多目标优化算法求解Pareto最优前沿,深入分析了不同优化目标间的内在权衡与博弈关系。文中系统阐述了各储能单元的数学建模方法、系统运行约束条件的设定以及多目标优化问题的规范化处理流程,最终通过详细的仿真算例验证了所提模型与方法的有效性,充分展示了该调度策略在促进新能源消纳、降低系统综合运行成本和减少碳排放方面的巨大潜力与应用价值。; 适合人群:具备电力系统、能源经济或优化理论基础知识的研究生、科研人员及从事能源规划与调度的工程技术人员。; 使用场景及目标:①研究包含多种新型储能技术的综合能源系统协调调度问题;②学习如何建立电力系统多目标优化模型(涵盖经济性、环保性和运行稳定性);③掌握利用Matlab实现多目标优化算法并进行结果可视化分析与决策的方法。; 阅读建议:此资源以Matlab代码为核心,不仅提供了严谨的理论模型,更有完整的可运行代码实现。读者在学习时应结合代码深入理解模型构建的每一个细节,包括变量的定义、复杂约束的处理以及目标函数的加权聚合方法,并建议尝试修改模型参数或调整目标权重,以观察系统行为的动态变化,从而深化对多目标优化本质和工程应用的理解。

Code Virtualizer 3.1.4 Crack

Code Virtualizer 是一个强大的 Windows 应用程序代码混淆系统,它可以帮助开发人员保护他们的敏感代码区域免受逆向工程的影响,基于代码虚拟化的非常强大的混淆代码。

控件与插件之大全 1528

产业园区运营负责人如何精准匹配企业技术需求与科研成果?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

加壳工具简介

<br />1.程序编写语言: <br />常见的程序制作语言有:<br />Borland Delphi 6.0 - 7.0<br />Microsoft Visual C++ 6.0<br />Microsoft Visual Basic 5.0 / 6.0<br />还有汇编、易语言等。 很多软件都通过加壳保护来提高软件的破解难度,下面我们简单的介绍一下加壳工具。 <br />2.软件加壳工具介绍: <br />II 压缩壳介绍: <br />常见压缩壳有:ASPack、UPX、PeCompact、N

Hank's Techblog 4574

A股分钟数据涵盖股票、ETF、可转债及指数四大类 每条数据记录包含精确到分钟的时间戳,以及开盘价、最高价、最低价、收盘价、成交量、成交额六个核心字段 部分数据还提供前收盘价作为参考 股票与ETF数据细

A股分钟数据涵盖股票、ETF、可转债及指数四大类。每条数据记录包含精确到分钟的时间戳,以及开盘价、最高价、最低价、收盘价、成交量、成交额六个核心字段。部分数据还提供前收盘价作为参考。股票与ETF数据细分至1分钟、5分钟等周期,可转债在交易时段内逐笔生成分钟快照,指数数据则同步覆盖上证、深证等主要宽基指数,便于观察市场整体走势。 数据源:CMES金融数据库

产业园区运营负责人如何借助平台实现创新资源的动态配置与精准对接?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

代码混淆不一定要花大价钱,Code Virtualizer也能轻松搞定!

任何创建创新性应用程序,DLL或设备驱动程序的开发人员都希望将代码尽可能机密,以避免第三方公司/开发人员研究应用程序内的代码并为自己的利益而窃取代码。一些开发人员使用外部保护系统来打包应用程序并保护其免受攻击者的侵害,但是大多数时候,这些保护系统无法提供他们所需要的强度,从而使开发人员在完全解压缩应用程序后完全感到沮丧。 市面很多代码保护软件,虽然功能强大,但同样价格昂贵,小编今天为大家推荐一款性价比高的代码混淆软件Code Virtualizer。 Code Virtualizer不能像普通的打包器那

mnrssj的博客 2190

基于变频控制的多相交错LLC谐振变换器闭环仿真(Simulink仿真实现)

内容概要:本文系统介绍了基于变频控制的多相交错LLC谐振变换器在Simulink环境下的闭环仿真研究,涵盖了系统建模、关键参数设计、变频控制策略(如PFM)的实现以及闭环控制系统构建与仿真验证的完整流程。重点阐述了如何通过调节开关频率实现对输出电压的精确控制,并结合多相交错技术有效降低输入输出电流纹波,提升变换器的功率密度、转换效率及动态响应性能。文中配套提供了完整的Simulink仿真模型、详细的计算书与参考文献,帮助读者深入理解LLC谐振变换器的工作原理、谐振特性与工程设计方法。; 适合人群:具备扎实的电力电子技术、自动控制理论基础,熟悉Simulink仿真平台操作,从事开关电源、新能源变换器、车载充电机、高效率DC-DC变换器研发等领域的硕士研究生、工程师及科研人员。; 使用场景及目标:①深入掌握LLC谐振变换器的核心工作原理与变频控制(PFM)的实现机制;②学习多相交错技术在抑制电流纹波、实现均流方面的工程应用;③实践完整的闭环控制系统设计、仿真与调试,包括控制器参数整定与动态性能分析;④为学术论文撰写、毕业课题研究或工业级产品开发提供可靠的技术参考与仿真原型。; 阅读建议:此资源以Simulink仿真实现为核心,兼具理论深度与工程实践价值。建议读者在学习过程中,务必结合所提供的仿真模型与计算书,亲自动手搭建系统,反复调整控制参数(如PI控制器增益、频率调节范围),并仔细观察系统的启动、负载突变、输入电压扰动等动态响应过程,从而深刻理解控制策略的设计逻辑与系统性能的优化方法。

[逆向工程]什么是加壳与脱壳(三)

压缩壳(UPX、ASPack)加密壳(Themida、VMProtect)虚拟化保护壳(Code Virtualizer)混合型商业壳(WinLicense)// 典型壳程序入口特征pushad // 保存寄存器状态call $+5 // 获取当前EIPpop ebp // 建立基址sub ebp, 5 // 计算偏移// 解密循环开始inc esi加壳与脱壳的对抗本质上是软件安全攻防的微观体现。

曼岛_的博客 2472

三相充电桩维也纳PFC+三电平LLC谐振变换器三电平PSIM仿真设计(Simulink仿真实现)

内容概要:本文围绕三相充电桩中的维也纳PFC(Vienna Power Factor Correction)与三电平LLC谐振变换器展开,重点介绍其在PSIM和Simulink环境下的仿真设计与实现。通过构建三相维也纳PFC的闭环控制模型,实现中点电位平衡、无功补偿及双载波SVPWM调制策略;同时设计三电平LLC谐振变换器,结合变频与移相混合控制策略,实现高效、高功率密度的直流充电变换。仿真内容涵盖主电路拓扑设计、控制策略建模、闭环系统搭建及关键参数优化,形成从前端整流到后级隔离变换的完整系统级解决方案,适用于高性能电动汽车充电桩的研发与教学实践。; 适合人群:具备电力电子与电力系统基础知识,从事新能源汽车充电技术、电源变换器设计等相关领域的研究生、工程师及科研人员。; 使用场景及目标:①掌握三相维也纳PFC的工作原理与中点电位控制方法;②深入理解三电平LLC谐振变换器的变频+移相复合控制机制;③实现从建模、仿真到参数调试的全流程技术实践,支撑高性能充电系统的开发与验证; 阅读建议:建议结合PSIM/Simulink软件动手搭建仿真模型,重点关注控制环路设计、关键波形分析与系统稳定性评估,并参照文中提供的参数设置与调试技巧,深入理解多电平变换器与谐振拓扑的协同工作机理。

Calibre LVS效率翻倍秘籍:用Hierarchical Flow处理亿级晶体管设计的5个关键阶段

本文详细解析了如何利用Hierarchical Flow技术提升Calibre LVS在亿级晶体管SoC设计中的验证效率。通过五个关键阶段的分层验证流程,包括顶层抽象验证、模块级独立验证等,可显著降低内存占用40-60%,缩短迭代周期50-70%,特别适用于SMIC等先进工艺节点。文章还分享了算力资源优化、并行化处理等实战技巧,帮助工程师应对大规模芯片验证挑战。

sam99的博客 769

关于Code Virtualizer pcode解密的一种方法

原文链接:http://bbs.pediy.com/showthread.php?t=137265 【详细过程】   1.VM的解密算法    一般情况下Code Virtualizer的解密有三个运算:add,sub,xor,有如下计算;      loads/b/w/d

学习........ 2060

第18届全国大学生智能汽车竞赛四轮车开源讲解【2.5】-- 图像处理实战:从二值化到边缘检测的工程优化

本文深入讲解了第18届全国大学生智能汽车竞赛四轮车开源项目中图像处理的核心实战技术。文章聚焦于二值化与边缘检测两大关键环节,详细对比了大津法与索贝尔算子的工程应用与优化策略,并分享了遮光、偏振片等物理抗干扰技巧,旨在帮助参赛者构建稳定高效的图像预处理流水线,为赛道识别奠定坚实基础。

weixin_29279047的博客 101

Themida / Winlicense (TM / WL)脱壳总结,Themida脱壳,Winlicense脱壳各个版本区别总结

个人总结,不一定十分准确,请勿引用! (一), Themida和不用license的Winlicense脱壳就不说了,直接上脚本脱壳。   (二), 先看看不同版本OEP的一些小特征: 2.1.X.X版本之后的OEP特征(2.0.8.0,2.1.0.10,2.1.3.32等)   2.1版本之前的OEP特征,如(2.0.3.0,1.8.2.0,1.885等):   Te

zhw309的专栏 2万+

Frida实战:如何用adb快速连接网易mumu模拟器进行参数Hook(附常见CPU架构问题排查)

本文详细介绍了如何使用Frida和adb快速连接网易MuMu模拟器进行参数Hook,包括环境配置、架构适配、Frida-server部署及常见问题排查。特别针对CPU架构兼容性问题提供了实用解决方案,帮助开发者高效完成逆向调试任务。

weixin_29274969的博客 290

Tessent_StdcellLib

第二种为 Tessent Cell lib,既可用于功能仿真,也可以用于测试逻辑插入。lib包含了用于仿真的功能信息,也包含DFT cell属性。如何使用tessent工具将stdcell verilog 仿真模型转换为tessent自己的lib。运行后工具会生成一个atpg的lib文件,打开文件,找到一个带SI的DFF,只有功能描述。tessnt lib分为两种,第一种为ATBG lib,可以用于仿真;打开生成的lib文件,多了dft_cell_selection。第二部:编写attributes文件。

qq_40411444的博客 2136

【转】脱壳工具

脱壳工具http://www.pediy.com/tools/unpacker.htm 文件类型侦测工具 peid 0.94

学习........ 4392

智能音箱开发者必看:CEVA-BX vs Cadence HiFi音频DSP实战选型指南(附功耗对比表)

本文深入对比了CEVA-BX和Cadence HiFi两大音频DSP架构在智能音箱开发中的性能差异,涵盖语音唤醒、多麦克风阵列处理等核心场景。通过实测数据和功耗对比表,为开发者提供选型参考,帮助优化产品性能和能效表现。

weixin_29309213的博客 227

Oreans代码混淆,软件保护工具Code Virtualizer与Themida新版发布,下载戳这里!

近日,oreans旗下代码搅乱系统Code Virtualizer与windows软件保护系统Themida分别更新了v2.2.2与v2.4.6版本,需要的小伙伴立即下载体验吧! Code Virtualizer v2.2.2 Code Virtualizer 是一个强大的代码搅乱系统。它可以帮助软件开发者保护他们软件内重要和敏感的代码区,防止他人使用逆向工程,而且它只消耗最小的系统资源。

HDrelease的博客 2365

拯救者R7000用户实测:用华为电脑管家11.0版搞定MatePad Pro多屏协同(附驱动与显卡避坑指南)

本文详细介绍了如何在非华为笔记本联想拯救者R7000上安装华为电脑管家11.0版,实现与MatePad Pro的多屏协同功能。从驱动优化到显卡配置,提供了全面的避坑指南和实用技巧,帮助用户解决连接失败等常见问题,提升跨设备生产力体验。

weixin_30788619的博客 398

【Proteus仿真】74HC595+74LS154驱动显示16X16点阵

【Proteus仿真】74HC595+74LS154驱动显示16X16点阵

perseverance51博客 2893

CODE VIRTUALIZER v 1.0.1.0

 

Linhanshi Blog 1434

【Java基础篇】Java重要特性,JDK,JRE,JVM区别和联系,环境变量

JDK使用时的执行流程: • 开发者视角(需要开发java程序):需要安装JDK a. 首先使用JDK调用Tools&Tool APIs(开发者工具)编写好Java程序--xxx.java b. 再次调用Tools&Tool APIs中的javac.exe(编译程序)来编译.java文件(将java文件编译成字节码.class文件) c. 调用java.exe来启动JRE d. 在JRE上运行JAVA字节码(加载特定的.class文件,调用这个class文件中的main方法

Yaoyao2024的博客 2163
上一篇: vbs 一些脚本
下一篇: MS06-040 Remote Code Execution Proof of Concept
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值