首页 \ 问答 \ 访问BlueStacks的应用程序(WhatsApp)数据库(Acessing BlueStacks' application (WhatsApp) database)

访问BlueStacks的应用程序(WhatsApp)数据库(Acessing BlueStacks' application (WhatsApp) database)

我试图转储我的联系人的用户名,状态和上次看到的数据。

由于WhatsApp没有API,我将其安装在BlueStacks上,并尝试拍摄可能存储这些详细信息的数据库的快照。

我有几个问题:

  1. 找不到数据库。 BlueStacks在哪里存储其应用程序数据? 更具体地说,我在哪里可以找到WhatsApp用户数据?
  2. 如果这不是一个可行的方法,是否有另一种方式以编程方式提取我正在寻找的数据?

提前致谢!


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:

  1. Can't find the database. Where does BlueStacks store its Application data? More specifically, where can I find the WhatsApp user data?
  2. 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
更新时间:2023-03-08 09:03

最满意答案

sizealign是作为完整类型使用时类的大小和对齐方式。 也就是说,如果创建了完整类型为该类型的对象(如定义该类型的变量或使用该类型的new类型)。

大小仅仅是它占用的字节数。 所以size=16意味着当用作完整类型时,它总是占用16个字节。

对齐方式告诉您可以放置​​对象的位置: align=8表示对象的地址必须是8的整数倍。

如果该类用作基类,则base sizebase align提供大小和对齐方式。 它们之所以不同,是因为C ++标准允许对象在用作基类时使用较少的填充。

所以让我们看看你的例子(我假设你在第一种情况下在double之前实际上有int )。 我也省略了publicprivate因为在这里它们不会改变任何东西(如果你有公共或私人数据成员,他们原则上可以改变某些东西,但我不知道是否有编译器利用这些)。 我也猜测intdouble的大小和对齐(实际上我假设的值是非常常见的选择,并解释你得到的值)。

所以在第一种情况下(我假设)你有

class A
{
  int m_number;
  double m_nothing;
};

现在int具有大小和对齐4 ,而double具有大小和对齐8

那么让我们来完成编译器的工作并构建我们的类。

首先,我们有m_number ,它占用4个字节。 我们必须按照给定的顺序放置成员,所以m_numberA的开头:

iiii

到目前为止,我们的大小为4(int的四个字节)和对齐4(因为int具有对齐4)。 但是现在我们必须添加一个double(size和alignment 8)。 由于直接在int之后,我们在(相对)地址4处,我们没有正确地对齐double,所以我们必须添加4个填充字节(我将用*标记)以达到8的倍数。因此我们为我们的班级获得:

iiii****dddddddd

现在,如果这个类被用作基类,我们就完成了。 因此,我们需要base size=16base align=8 (我们需要一个8的对齐才能正确地进行double对齐)。

对于完整的对象,还有另外一个考虑因素:标准要求在数组中,对象彼此相互之间没有间隙。 也就是说,对象之后的第一个字节必须正确对齐下一个对象。 这最终意味着完整对象的大小必须是其对齐的倍数。

现在我们发现的对象布局已经满足了这个要求。 因此,我们可以将它用于完整的对象。 因此,对于完整的对象,我们得到size=16align=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 and align 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 with new).

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 and base 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 the double in the first case). I'm also omitting the public and private 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 of int and double (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 alignment 4, and double has size and alignment 8.

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, so m_number goes at the beginning of A:

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 and base 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 and align=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 an int, 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 the double to be correctly aligned, the object again has to start at an address which is a multiple of 8. Therefore we have base 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 have align=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 of S2 will be just 24. Indeed, the objects of type S1 will, as complete object, look like

c*******ddddddddc*******ddddddddc*******

while those of type S2 will look like

ddddddddddddddddccc*****

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 calls size.

相关问答

更多
  • 让我们看看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打印到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 ...

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。