Why I change the string s1 constant by reflection in java, the other s2, s3 also changed? - reflection

environment messages:
(env) λ java -version
openjdk version "1.8.0_242"
OpenJDK Runtime Environment (build 1.8.0_242-xxxxxx_JDK_xxxxx)
OpenJDK 64-Bit Server VM (build 25.242-b08, mixed mode)
/*
* Copyright (c) Google Technologies Co., Ltd. 2021-2021. All rights reserved.
*/
package corejava.v1ch05.practice;
import java.lang.reflect.Field;
import java.util.Random;
public class ChangeString {
private static void printAddress(String message) throws IllegalAccessException, NoSuchFieldException {
Field f = message.getClass().getDeclaredField("value");
f.setAccessible(true);
char[] v = (char[])f.get(message);
System.out.println("message hashcode: " + message.hashCode());
System.out.println("message real identity: " + System.identityHashCode(message));
System.out.println("v real identity: " + System.identityHashCode(v));
System.out.println();
}
private static void change(String message) throws NoSuchFieldException, IllegalAccessException {
System.out.println(System.identityHashCode(message));
Field f = message.getClass().getDeclaredField("value");
System.out.print("Accessible: " + f.isAccessible());
f.setAccessible(true);
char[] v = (char[])f.get(message);
System.out.println(System.identityHashCode(v));
Random random = new Random();
char randomizedCharacter = (char) (random.nextInt(26) + 'a');
v[0] = randomizedCharacter;
System.out.println();
}
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
String s1 = " abcd";
String s2 = " abcd";
String s3 = new String(" abcd");
printAddress(s1);
printAddress(s2);
printAddress(s3);
change(s1);
printAddress(s2);
printAddress(s3);
System.out.print(s1 + " " + s2 + " " + s3);
}
}
The results are as follows:
message hashcode: 32539746
message real identity: 460141958
v real identity: 1163157884
message hashcode: 32539746
message real identity: 460141958
v real identity: 1163157884
message hashcode: 32539746
message real identity: 1956725890
v real identity: 1163157884
460141958
Accessible: false1163157884
message hashcode: 32539746
message real identity: 460141958
v real identity: 1163157884
message hashcode: 32539746
message real identity: 1956725890
v real identity: 1163157884
qabcd qabcd qabcd
As I know, the string constant is stored in the string constant pool.
store location(maybe it's wrong!):
jdk1.6 Method Area
jdk1.7 heap memory
jdk1.8 local memory
I changed the s1, the s2, s3 reference also changed. It really mixed me up!
do the s1, s2, s3's final value " abcd" has the same memory address?

As I know, the string constant is stored in the string constant pool. store location(maybe it's wrong!): jdk1.6 Method Area jdk1.7 heap memory jdk1.8 local memory
Yes it’s wrong. As wrong as a statement can be. All objects are stored in the heap memory. Because that’s how heap memory is defined:
The Java Virtual Machine has a heap that is shared among all Java Virtual Machine threads. The heap is the run-time data area from which memory for all class instances and arrays is allocated.
The constant pool is nothing you have to think about. All that matters, is that all string literals of the same contents, i.e. " abcd", refer to the same object.
Moreover, a string literal always refers to the same instance of class String. This is because string literals - or, more generally, strings that are the values of constant expressions (§15.29) - are "interned" so as to share unique instances, as if by execution of the method String.intern (§12.5).
Since they refer to the same object, hacking into the internals to manipulate what is supposed to be immutable, will make the change observable through all references.
The array wrapped by String objects is an implementation detail, so whether creating a new string via new String(" abcd") will create a new array or just let the two equal strings share the same array, is an implementation detail too. If they share the same array, manipulating that array affects both strings.
The “identity hash code” is neither, a “true identity” nor an address. It’s, like the ordinary hash code, a number helping certain data structures, like HashSet, to look up objects efficiently. Since there is no limit on the number of objects an implementation can create, but the hash code is just a 32 bit number, two objects still can have the same identity hash code. Further, objects can be moved around in the memory, but the identity hash code of an object will never change. So, obviously, it can’t be an address.
In your particular output, they two distinct string instances happened to have different identity hash codes and all strings happened to truly refer to the same array, which the behavior after the modification proved better than the hash codes.

Related

Parse EC Public key

I an working on ECIES and need to load peer public key.
Load EC Public key
I an using ECDH and need to load peer public key.
When I try to load public key from PEM file , seems no issue
Issue here:
EVP_PKEY * get_peer_key()
{
// base64 certificate data of alice_pub_key.pem
char *buffer= "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEjWrT7F97QrSqGrlIgPK8dphNBicNO6gDLfOIMjhF2MiLuuzd7L7BP+bLCuNtKKe/2dOkgPqgXv4BFWqgp6PZXQ=="`
// calculate buffer length
int l = strlen(buffer)
//create bio from buffer
BIO *in = BIO_new_mem_buf(buffer,l)
//gnerate ec key
EC_KEY *eckey = PEM_read_bio_EC_PUBKEY(in,NULL,NULL,NULL)` // ==> FAIL
//need to convert to EVP format
EVP_PKEY *peerKey = EVP_PKEY_new()
//assign ec key evp
if(EVP_PKEY_assign_EC_KEY(peerKey,eckey) != 1 )
printf("\n error hapened");
return peerKey;
}
Works fine:
EVP_PKEY * get_peer_key()
{
//Load PEM format file
char * infile = "alice_pub_key.pem";
//create bio
BIO *in = BIO_new(BIO_s_file());
//read bio file
BIO_read_filename(in , infile);
//create eckey
EC_KEY *eckey = PEM_read_bio_EC_PUBKEY(in,NULL,NULL,NULL); // ==> success
// create peer key
EVP_PKEY *peerKey = EVP_PKEY_new();
//assign public key
if(EVP_PKEY_assign_EC_KEY(peerKey,eckey) != 1 )
printf("\n error hapened");
return peerKey;
}
Can some one suggest whats going wrong while reading base64 data of pem file
There are two ways of solving this:
Creating a PEM using a header and footer line and line breaks (at the 64th character;
Base 64 decoding the text and then handling it by parsing the resulting ASN.1 / DER binary;
I'd prefer the latter, as I abhor adding lines and such, it is error prone at best, and string manipulations should be avoided where possible.
Note that this assumes that the base 64 contains a SubjectPublicKeyInfo structure which I've shown you earlier. Otherwise you may have to find out how to parse a X9.62 structure or just a point.

Finding pointer with 'find out what writes to this address' strange offset

I'm trying to find a base pointer for UrbanTerror42.
My setup is as followed, I have a server with 2 players.
cheat-engine runs on client a.
I climb a ladder with client b and then scan for incease/decrease.
When I have found the values, I use find out what writes to this address.
But the offset are very high and point to empty memory.
I don't really know how to proceed
For the sake of clarity, I have looked up several other values and they have the same problem
I've already looked at a number of tutorials and forums, but that's always about values where the offsets are between 0 and 100 and not 80614.
I would really appreciate it if someone could tell me why this happened and what I have to do/learn to proceed.
thanks in advance
Urban Terror uses the Quake Engine. Early versions of this engine use the Quake Virtual Machine and the game logic is implemented as bytecode which is compiled into assembly by the Quake Virtual Machine. Custom allocation routines are used to load these modules into memory, relative and hardcoded offsets/addresses are created at runtime to accommodate these relocations and do not use the normal relocation table method of the portable executable file format. This is why you see these seemingly strange numbers that change every time you run the game.
The Quake Virtual Machines are file format .qvm and these qvms in memory are tracked in the QVM table. You must find the QVM table to uncover this mystery. Once you find the 2-3 QVMs and record their addresses, finding the table is easy, as you're simply doing a scan for pointers that point to these addresses and narrowing down your results by finding those which are close in memory to each other.
The QVM is defined like:
struct vmTable_t
{
vm_t vm[3];
};
struct vm_s {
// DO NOT MOVE OR CHANGE THESE WITHOUT CHANGING THE VM_OFFSET_* DEFINES
// USED BY THE ASM CODE
int programStack; // the vm may be recursively entered
intptr_t(*systemCall)(intptr_t *parms);
//------------------------------------
char name[MAX_QPATH];
// for dynamic linked modules
void *dllHandle;
intptr_t entryPoint; //(QDECL *entryPoint)(int callNum, ...);
void(*destroy)(vm_s* self);
// for interpreted modules
qboolean currentlyInterpreting;
qboolean compiled;
byte *codeBase;
int codeLength;
int *instructionPointers;
int instructionCount;
byte *dataBase;
int dataMask;
int stackBottom; // if programStack < stackBottom, error
int numSymbols;
struct vmSymbol_s *symbols;
int callLevel; // counts recursive VM_Call
int breakFunction; // increment breakCount on function entry to this
int breakCount;
BYTE *jumpTableTargets;
int numJumpTableTargets;
};
typedef struct vm_s vm_t;
The value in EAX in your original screenshot should be the same as either the codeBase or dataBase member variable of the QVM structure. The offsets are just relative to these addresses. Similarly to how you deal with ASLR, you must calculate the addresses at runtime.
Here is a truncated version of my code that does exactly this and additionally grabs important structures from memory, as an example:
void OA_t::GetVM()
{
cg = nullptr;
cgs = nullptr;
cgents = nullptr;
bLocalGame = false;
cgame = nullptr;
for (auto &vm : vmTable->vm)
{
if (strstr(vm.name, "qagame")) { bLocalGame = true; continue; }
if (strstr(vm.name, "cgame"))
{
cgame = &vm;
gamestatus = GSTAT_GAME;
//char* gamestring = Cvar_VariableString("fs_game");
switch (cgame->instructionCount)
{
case 136054: //version 88
cgents = (cg_entities*)(cgame->dataBase + 0x1649c);
cg = (cg_t*)(cgame->dataBase + 0xCC49C);
cgs = (cgs_t*)(cgame->dataBase + 0xf2720);
return;
Full source code for reference available at OpenArena Aimbot Source Code, it even includes a video overview of the code.
Full disclosure: that is a link to my website and the only viable resource I know of that covers this topic.

Is RSACryptoServiceProvider working correctly?

I'm using .NET's implementation of RSA, and two things looked odd to me. I'd like to confirm that it's operating properly.
Background
Using System.Security.Cryptography.RSACryptoServiceProvider with 2048-bit keyword size to perform asymmetric encryption/decrpytion, initially following the example in this question, "AES 256 Encryption: public and private key how can I generate and use it .net".
As a first implementation, this seems to work:
public const int CSPPARAMETERS_FLAG = 1; // Specifies RSA: https://msdn.microsoft.com/en-us/library/ms148034(v=vs.110).aspx
public const bool USE_OAEP_PADDING = false;
public const int KEYWORD_SIZE = 2048;
public static byte[] Encrypt(byte[] publicKey, byte[] dataToEncrypt)
{
var cspParameters = new System.Security.Cryptography.CspParameters(CSPPARAMETERS_FLAG);
byte[] encryptedData = null;
using (var rsaProvider = new System.Security.Cryptography.RSACryptoServiceProvider(cspParameters))
{
try
{
rsaProvider.PersistKeyInCsp = false;
rsaProvider.ImportCspBlob(publicKey);
encryptedData = rsaProvider.Encrypt(dataToEncrypt, USE_OAEP_PADDING);
}
finally
{
rsaProvider.PersistKeyInCsp = false;
rsaProvider.Clear();
}
}
return encryptedData;
}
public static byte[] Decrypt(byte[] privateKey, byte[] dataToDecrypt)
{
var cspParameters = new System.Security.Cryptography.CspParameters(CSPPARAMETERS_FLAG);
byte[] encryptedData = null;
using (var rsaProvider = new System.Security.Cryptography.RSACryptoServiceProvider(cspParameters))
{
try
{
rsaProvider.PersistKeyInCsp = false;
rsaProvider.ImportCspBlob(privateKey);
encryptedData = rsaProvider.Decrypt(dataToDecrypt, USE_OAEP_PADDING);
}
finally
{
rsaProvider.PersistKeyInCsp = false;
rsaProvider.Clear();
}
}
return encryptedData;
}
After looking into these methods a bit more, it seems that the public key that I've been generating as from the example seemed to have a lot of very predictable data at its start, and it was 276-bytes long.
Apparently rsaProvider.ExportCspBlob(bool includePrivateParameters) is a functional alternative to rsaProvider.ExportParameters(bool includePrivateParameters); the main difference is that the blob is already serialized as a byte[] while the other emits the object version, RSAParameters.
Two observations about the methods:
The .Exponent is always 0x010001$=65537$.
The exported blobs contain 17 extra bytes versus the serialized typed versions.
rsaProvider.ExportCspBlob():
Public key is 276 bytes.
Private key is 1172 bytes.
RSAParameters:
Public key is 259 bytes.
.Exponent.Length = 3
.Modulus .Length = 256
Private key is 1155 bytes.
.D .Length = 256
.DP .Length = 128
.DQ .Length = 128
.Exponent.Length = 3
.InverseQ.Length = 128
.Modulus .Length = 256
.P .Length = 128
.Q .Length = 128
The extra 17 bytes appear to be at the header of the binary blob.
Concerns
From this, two concerns:
Is it okay for the exponent to not be random?
If the exponent is defined as a constant, then it'd seem like that's another 3 bytes I could shave off the serialization?
Another question, Should RSA public exponent be only in {3, 5, 17, 257 or 65537} due to security considerations?, seems to suggest that $\left{3, 5, 17, 257, 65537\right}$ are all common values for the exponent, so 0x101$=65537$ seems reasonable if it's true that there's no harm in always using the same constant exponent.
Are the 17 extra bytes an information leak?
Do they represent the option parameters like key length and method?
Is it a good idea to be transmitting option parameter information when I already know that both the sender and receiver are using the same, hard-coded method?
Question
Is RSACryptoServiceProvider's behavior a cause for concern, or are these things normal?
Update 1
In Should RSA public exponent be only in {3, 5, 17, 257 or 65537} due to security considerations?, the accepted answer starts off by noting:
There is no known weakness for any short or long public exponent for RSA, as long as the public exponent is "correct" (i.e. relatively prime to p-1 for all primes p which divide the modulus).
If this is so, then I'd guess that the apparently-constant exponent of 0x010001$=65537$ is sufficient as long as it's relatively prime to $p-1$. So, presumably the .NET implementation of RSA checks for this condition.
But then what does RSACryptoServiceProvider do if that condition isn't satisfied? If it selects a different exponent, then that'd seem to leak information about $p$ whenever the exponent isn't 0x010001. Or, if a different key is selected, then it'd seem like we can just assume that the exponent is always 0x010001 and omit it from the serialization.
Everything reported is normal, and non-alarming.
It is perfectly OK for the public exponent e to be short and non-random. e = 216+1 = 65537 = 0x010001 is common and safe. Some authorities mandate it (or some range including it). Using it (or/and something significantly larger than the bit size of the public modulus) gives some protection against some of the worst RSA paddings.
No, the 17 extra bytes in the public key are unlikely to be an information leak; they more likely are a header part of the data format chosen for an RSA public key by the software you use. My guess is that you are encountering the MS-specific format detailed in this answer (perhaps, within endianness), which also uses precisely 276 bytes for an RSA public key with a 2048-bit public modulus. In that case, you should find that the extra bytes are always the same (thus they demonstrably leak nothing). And there are countless more subtle ways to leak information about the private key, like in the public modulus itself.
Many RSA key generators used in practice, including I guess RSACryptoServiceProvider, first choose e, then somewhat avoid generating primes p such that gcd(e, p-1) ≠ 1. Since e = 65537 is prime, it is enough that ( p % e ) ≠ 1, and this is easily checked, or otherwise insured by the process generating p.

obfuscate password in qt

I want to store a password (no hash) on my disk. it's nothing sensitive but i just don't want it in plaintext on my disk.
what i tried till now is:
converting the string in binary and XOR it with the binary of a key.
bool ok = true;
QByteArray qbaPW("mypass");
long long intPW = qbaPW.toHex().toLongLong( &ok, 16 );
QString binPW = QString::number( intPW, 2);
but the thing is, that it only works with short passwords. if they are too long intPW gets too big for longlong. any ideas how can avoid that thing?
cheers
A QByteArray is like a char array[len] in C. You can access individual members and do whatever you please with them. For example:
QByteArray const key("mykey");
QByteArray password("password");
for (int ik = 0, ip = 0;
ip < password.length();
++ ip, ik = (ik+1 < key.length() ? ik+1 : 0)) {
password[ip] = password[ip] ^ key[ik];
}
Since this just XORs with the key, you repeat this procedure to decrypt the password. A good key will be generated randomly and will be longer than the longest password you envisage (say 64 characters).
Do note that this method is only reasonably safe if the users are explicitly informed not to reuse any other password in your application - otherwise you're essentially leaking passwords that are supposed to be secure.

Bind void * pointer to C++/Cli pointer of elementary type

I do some thin wrapper of some scientific library (http://root.cern.ch) from unmanaged to managed world using C++ cli.
Reading of the special file format (which is the main goal) is implemented through:
1) Once a lifetime call of SetBranchAddress(const char name, void* outputVariable) to let it know an address of your variable
2) Than you N time call GetEntry(ulong numberOfRow) wthich fills this void* outputVariable with the appropriate value;
I put this example of usage :
double myValue; //this field will be filled
//We bind myValue to the 'column' called "x" stored in the file"
TTree->SetBranchAddress("x", &myValue);
// read first "entry" (or "row") of the file
TTree->GetEntry(0);
// from that moment myValue is filled with value of column "x" of the first row
cout<<"First entry x = "<<myValue<<endl;
TTree->GetEntry(100); //So myValue is filled with "x" of 101 row
...
So in C++/CLI code the problem is with binding managed elementary types to this void * pointer;
I have tried 3 approaches:
namespace CppLogicLibrary {
public ref class SharpToRoot
{
double mEventX;
double *mEventY;
IntPtr memEventZ;
///Constructor
SharpToRoot()
{
mEventy = new double();
memEventZ= Marshal::AllocHGlobal(sizeof(double));
}
void SetBranchAddresses()
{
pin_ptr<double> pinnedEventX = &mEventX;
mTree->SetBranchAddress("ev_x", pinnedEventX);
mTree->SetBranchAddress("ev_y", mEventY);
mTree->SetBranchAddress("ev_z", memEventZ.ToPointer());
...
//now I read some entry to test... just in place
mTree->GetEntry(100);
mTree->GetEntry(101);
double x = mEventX;
double y = *mEventY
double z = (double)Marshal::PtrToStructure(memEventZ, Double::typeid);
}
...
All of 3 variants are compiled with no errors, goes with no exceptions... BUT fills its (void *) values with some rubbish value like 5,12331E-305. In unmanaged code all works fine.
What could be the error with such void* to C++/CLI elementary types binding?
The problem was that internally data was presented by floats inside of this library. So, when it was mapped and processed as doubles on the C# side, it gave 5,12331E-305.
Each of this 3 variats worked. And, from my point of view, using of
pin_ptr pinnedEventX = &mEventX;
was improper in this case, because it doesn't persist between functions execution;
What I'm not sure, why this "float" situation was handled in native C++. As I wrote before, there wasn't any problem.

Resources