访问BlueStacks的应用程序(WhatsApp)数据库(Acessing BlueStacks' application (WhatsApp) database)
我试图转储我的联系人的用户名,状态和上次看到的数据。
由于WhatsApp没有API,我将其安装在BlueStacks上,并尝试拍摄可能存储这些详细信息的数据库的快照。
我有几个问题:
- 找不到数据库。 BlueStacks在哪里存储其应用程序数据? 更具体地说,我在哪里可以找到WhatsApp用户数据?
- 如果这不是一个可行的方法,是否有另一种方式以编程方式提取我正在寻找的数据?
提前致谢!
I am trying to get a dump of my contacts' user names, statuses and last seen data.
Since WhatsApp doesn't have an API, I installed it on BlueStacks and am trying to take a snapshot of the database where these details might be stored.
I have a couple of problems:
- Can't find the database. Where does BlueStacks store its Application data? More specifically, where can I find the WhatsApp user data?
- If this is not a feasible way to go about it, is there another way to programmatically extract the data I am looking for?
Thanks in advance!
原文:https://stackoverflow.com/questions/19752384
最满意答案
size
和align
是作为完整类型使用时类的大小和对齐方式。 也就是说,如果创建了完整类型为该类型的对象(如定义该类型的变量或使用该类型的new
类型)。大小仅仅是它占用的字节数。 所以
size=16
意味着当用作完整类型时,它总是占用16个字节。对齐方式告诉您可以放置对象的位置:
align=8
表示对象的地址必须是8的整数倍。如果该类用作基类,则
base size
和base align
提供大小和对齐方式。 它们之所以不同,是因为C ++标准允许对象在用作基类时使用较少的填充。所以让我们看看你的例子(我假设你在第一种情况下在
double
之前实际上有int
)。 我也省略了public
和private
因为在这里它们不会改变任何东西(如果你有公共或私人数据成员,他们原则上可以改变某些东西,但我不知道是否有编译器利用这些)。 我也猜测int
和double
的大小和对齐(实际上我假设的值是非常常见的选择,并解释你得到的值)。所以在第一种情况下(我假设)你有
class A { int m_number; double m_nothing; };
现在
int
具有大小和对齐4
,而double具有大小和对齐8
。那么让我们来完成编译器的工作并构建我们的类。
首先,我们有
m_number
,它占用4个字节。 我们必须按照给定的顺序放置成员,所以m_number
在A
的开头:iiii
到目前为止,我们的大小为4(int的四个字节)和对齐4(因为int具有对齐4)。 但是现在我们必须添加一个double(size和alignment 8)。 由于直接在int之后,我们在(相对)地址4处,我们没有正确地对齐double,所以我们必须添加4个填充字节(我将用
*
标记)以达到8的倍数。因此我们为我们的班级获得:iiii****dddddddd
现在,如果这个类被用作基类,我们就完成了。 因此,我们需要
base size=16
和base align=8
(我们需要一个8的对齐才能正确地进行double对齐)。对于完整的对象,还有另外一个考虑因素:标准要求在数组中,对象彼此相互之间没有间隙。 也就是说,对象之后的第一个字节必须正确对齐下一个对象。 这最终意味着完整对象的大小必须是其对齐的倍数。
现在我们发现的对象布局已经满足了这个要求。 因此,我们可以将它用于完整的对象。 因此,对于完整的对象,我们得到
size=16
和align=8
。现在考虑顺序颠倒的情况:
class A { double m_nothing; int m_number; };
现在我们必须从
double
开始:dddddddd
接下来,我们必须添加
int
。 事实证明,下一个空闲的地方已经正确地对齐了一个int
,因此我们可以将它追加:ddddddddiiii
现在作为基础对象使用,我们已经准备好了。 如您所见,我们只需要12个字节,因此
base size=12
。 当然,double
正确对齐,对象又必须从8的倍数开始。因此,我们有base align=8
。然而,对于作为完整对象的起诉,我们现在发现下一个地址将位于12位,这对于
double
成员来说没有正确对齐。 因此,我们必须添加填充字节,直到我们再次到达正确对齐的地址:ddddddddiiii****
正如你所看到的,现在我们需要16个字节,因此
size=16
。 由于双倍,我们仍然有align=8
。请注意,对齐要求会显着影响类的大小。 考虑以下两种类型:
struct S1 { char c1; double d1; char c2; double d2; char c3; }; struct S2 { double d1; double d2; char c1; char c2; char c3; };
虽然两者都包含相同的成员,但
S1
上面的大小和路线的总数(非基数)为40,而S2
的总大小只有24个。事实上,S1
类型的对象将作为完整对象, 看起来像c*******ddddddddc*******ddddddddc*******
而
S2
型的则看起来像ddddddddddddddddccc*****
因此,最重要的是,对齐要求最高的成员应始终排在第一位。
另请注意,
sizeof
返回完整对象的大小,即类层次转储调用的size
。The
size
andalign
are the size and alignment of the class when used as complete type. That is, if you create objects whose complete type is that type (like defining variables of that type, or using that type withnew
).The size is simply the number of bytes it occupies. So
size=16
means when used as complete type, it always occupies 16 bytes.The alignment tells you where the object may be placed:
align=8
means the address of the object must be an integer multiple of 8.The
base size
andbase align
give the size and alignment in case the class is used as base class. The reason why they are different is that the C++ standard allows objects to use less padding when used as base class.So let's look specifically at your example (I'm assuming that you actually have the
int
before thedouble
in the first case). I'm also omitting thepublic
andprivate
because here they don't change anything (if you had both public or private data members, they could in principle change something, but I don't know if any compiler takes advantage of that). I'm also guessing the size and alignment ofint
anddouble
(actually the values I assume are pretty common choice, and explain the values you get).So in the first case (I assume) you have
class A { int m_number; double m_nothing; };
Now
int
has size and alignment4
, and double has size and alignment8
.So let's do the job of the compiler and build our class.
First, we have
m_number
, which occupies 4 bytes. We have to put the members in the order given, som_number
goes at the beginning ofA
:iiii
Up to now, we have size 4 (the four bytes for the int), and alignment 4 (because int has alignment 4). But now we have to add a double (size and alignment 8). Since directly after the int, we are at (relative) address 4, we are not correctly aligned for the double, so we have to add 4 padding bytes (which I'll mark with
*
) to get to a multiple of 8. Thus we get for our class:iiii****dddddddd
Now, if the class is used as base class, we are finished. Thus we habe
base size=16
andbase align=8
(we need an alignment of 8 in order to get the double aligned correctly).For the complete object, there's another consideration: The standard demands that in arrays, the objects follow each other without a gap in between. That is, the first byte after the object must be correctly aligned for the next object. Which ultimately means that the size of the complete object has to be a multiple of its alignment.
Now the object layout we've found already fulfils that requirement. Therefore we can use it unchanged also for the complete object. Therefore we get
size=16
andalign=8
for the complete object.Now consider the case where the order is reversed:
class A { double m_nothing; int m_number; };
Now we have to start with the
double
:dddddddd
Next, we have to add the
int
. As it turns out, the next free place is already correctly aligned for anint
, therefore we can just append it:ddddddddiiii
Now for the use as base object, we are ready. As you can see, we only needed 12 bytes, therefore
base size=12
. Of course for thedouble
to be correctly aligned, the object again has to start at an address which is a multiple of 8. Therefore we havebase align=8
.However for the sue as complete object, we now find that the next address would be at position 12, which is not correctly aligned for the
double
member. Therefore we have to add padding bytes until we reach a correctly aligned address again:ddddddddiiii****
As you can see, now we need 16 bytes, thus
size=16
. We still havealign=8
due to the double.Note that the alignment requirement can dramatically affect the size of a class. Consider for example the following two types:
struct S1 { char c1; double d1; char c2; double d2; char c3; }; struct S2 { double d1; double d2; char c1; char c2; char c3; };
While both contain the same members,
S1
will with the sizes and alignments above have a total (non-base) size of 40, while the total size ofS2
will be just 24. Indeed, the objects of typeS1
will, as complete object, look likec*******ddddddddc*******ddddddddc*******
while those of type
S2
will look likeddddddddddddddddccc*****
So the bottom line is that members with the highest alignment requirement should always come first.
Also note that
sizeof
returns the size of complete objects, that is, what the class hierarchy dump callssize
.
相关问答
更多-
让我们看看printf()调用的第一个参数。 "%d" + 1 这指向与ptr在下面的代码中所做的相同的事情。 char *ptr = "%d"; ptr = ptr + 1; 那么,增加一个指针是什么意思? 那么,我们提前指针sizeof(*ptr) * 1个字节。 所以,在记忆中我们有: %d\0 ^^ || |This is where ("%d" + 1) points to. This is where ("%d") points to. 所以,你的代码或多或少在功能上等同于: short ...
-
试图理解strace输出(trying to understand strace output)[2021-12-27]
strace打印到stderr,而不是标准输出。 您需要重定向2> echo1.txt以将stderr重定向到文件,或者只需使用strace -o echo1.txt将strace输出显式写入该文件。 strace prints to stderr, not stdout. You need should redirect with 2> echo1.txt in order to redirect stderr to a file, or just use strace -o echo1.txt to e ... -
那些是偏移到顶部(需要多个继承)和typeinfo(RTTI)指针。 从Itanium ABI (您不使用Itanium编译器,但它们的描述真的很好) : 到顶部的偏移将位置从位于虚拟表指针的对象内的位置放置到对象的顶部,该对象位于作为ptrdiff_t的虚拟表中。 它总是存在。 偏移量提供了一种使用虚拟表指针从任何基本子对象中找到对象顶部的方法。 这对于dynamic_cast尤其是必需的。 (在完整的对象虚拟表中,因此在其所有主基础虚拟表中,此偏移量的值将为零。[...]) typeinfo指针指向用于 ...
-
您没有在脚本中的任何位置设置argv0 。 Expect将它设置为脚本的名称。 你可以在expect -d输出中看到这个: $ cat arg.exp #!/usr/bin/expect set string [lindex $argv 0] send ${string} send_user "$argv0 [lrange $argv 0 2]\n" $ expect -d arg.exp "THIS IS THE FIRST ARG " expect version 5.45 argv[0] = expe ...
-
size和align是作为完整类型使用时类的大小和对齐方式。 也就是说,如果创建了完整类型为该类型的对象(如定义该类型的变量或使用该类型的new类型)。 大小仅仅是它占用的字节数。 所以size=16意味着当用作完整类型时,它总是占用16个字节。 对齐方式告诉您可以放置对象的位置: align=8表示对象的地址必须是8的整数倍。 如果该类用作基类,则base size和base align提供大小和对齐方式。 它们之所以不同,是因为C ++标准允许对象在用作基类时使用较少的填充。 所以让我们看看你的例子(我 ...
-
您的示例的主要问题是您如何处理结束字符。 如果您在输入中完全替换它们,输出将不再正确排列,因此没有任何意义。 要解决这个问题, readable_whitespace函数应该如下所示: def readable_whitespace(line): end = len(line.rstrip('\r\n')) return line[:end] + repr(line[end:])[1:-1] + '\n' 这将处理所有类型的结束序列,并确保在打印时正确显示行。 另一个小问题是由于拼写错误: ...
-
这看起来像编译器生成的代码,用于在析构函数被调用之后管理实际的内存释放,并且应该在析构函数代码之后立即执行。 That looks like the compiler-generated code to manage the actual memory deallocation after the destructor is called and should execute right after your destructor code.
-
它是封闭的( 1,2 )。 在你的情况下, Console.Write(i)将在动作调用时使用i值。 您首先将i递增for循环,然后在第二个循环中调用列表中的每个动作。 在每次行动的时刻i都有价值2 - 所以,你得到22作为输出。 要获得预期的结果,您应该创建i本地副本并使用它: for (int i = 0; i < 2; i++) { var temp = i; list.Add(() => Console.Write(temp)); } It is Closure (1, 2). ...
-
问题在于你的while循环附加到ip_address_list,它追加添加1个附加,循环然后再添加相同的ip,添加1追加,依此类推,这就是为什么你得到双打,只需移动第一个追加在循环之外修复它。 你的for循环真的是多余的,我在2行中做了同样的事情 import subprocess ipfirst=input("1st ip:") iplast=input("2nd ip:") currentip="144.122.152.13" ip_adresses_list=[] """this function ...
-
这返回一个指向本地i的指针: char_point cp = (char_point) &i; 和指向本地f的指针: char_point cp = (char_point) &f; 一旦函数返回,它们就会被释放 this returns a pointer to the local i: char_point cp = (char_point) &i; and a pointer to a local f: char_point cp = (char_point) &f; once the fun ...